diff --git a/packages/runtime-core/__tests__/componentProxy.spec.ts b/packages/runtime-core/__tests__/componentProxy.spec.ts index 02cc5f5f4e5..f37bfe3d9d8 100644 --- a/packages/runtime-core/__tests__/componentProxy.spec.ts +++ b/packages/runtime-core/__tests__/componentProxy.spec.ts @@ -217,4 +217,24 @@ describe('component: proxy', () => { `was accessed during render but is not defined` ).not.toHaveBeenWarned() }) + + test('should allow symbol to access on render', () => { + const Comp = { + render() { + if ((this as any)[Symbol.unscopables]) { + return '1' + } + return '2' + } + } + + const app = createApp(Comp) + app.mount(nodeOps.createElement('div')) + + expect( + `Property ${JSON.stringify( + Symbol.unscopables + )} was accessed during render ` + `but is not defined on instance.` + ).toHaveBeenWarned() + }) }) diff --git a/packages/runtime-core/src/componentProxy.ts b/packages/runtime-core/src/componentProxy.ts index e043d93eb4b..84f14ce462a 100644 --- a/packages/runtime-core/src/componentProxy.ts +++ b/packages/runtime-core/src/componentProxy.ts @@ -6,7 +6,8 @@ import { hasOwn, isGloballyWhitelisted, NOOP, - extend + extend, + isString } from '@vue/shared' import { ReactiveEffect, @@ -286,9 +287,10 @@ export const PublicInstanceProxyHandlers: ProxyHandler = { } else if ( __DEV__ && currentRenderingInstance && - // #1091 avoid internal isRef/isVNode checks on component instance leading - // to infinite warning loop - key.indexOf('__v') !== 0 + (!isString(key) || + // #1091 avoid internal isRef/isVNode checks on component instance leading + // to infinite warning loop + key.indexOf('__v') !== 0) ) { if (data !== EMPTY_OBJ && key[0] === '$' && hasOwn(data, key)) { warn(