diff --git a/packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts b/packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts index 59da8397..fed38fc3 100644 --- a/packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts +++ b/packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts @@ -326,4 +326,28 @@ describe('attribute fallthrough', () => { `
` ) }) + + it('should not warn when context.attrs is used during render', () => { + const Parent = { + render() { + return h(Child, { foo: 1, class: 'parent' }) + } + } + + const Child = defineComponent({ + props: ['foo'], + setup(_props, { attrs }) { + return () => [h('div'), h('div', attrs)] + } + }) + + const root = document.createElement('div') + document.body.appendChild(root) + render(h(Parent), root) + + expect(`Extraneous non-props attributes`).not.toHaveBeenWarned() + expect(root.innerHTML).toBe( + `
` + ) + }) }) diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 50b8498a..3eafc78d 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -28,7 +28,10 @@ import { } from '@vue/shared' import { SuspenseBoundary } from './components/Suspense' import { CompilerOptions } from '@vue/compiler-core' -import { currentRenderingInstance } from './componentRenderUtils' +import { + currentRenderingInstance, + markAttrsAccessed +} from './componentRenderUtils' export type Data = { [key: string]: unknown } @@ -428,7 +431,12 @@ export const SetupProxySymbol = Symbol() const SetupProxyHandlers: { [key: string]: ProxyHandler } = {} ;['attrs', 'slots'].forEach((type: string) => { SetupProxyHandlers[type] = { - get: (instance, key) => instance[type][key], + get: (instance, key) => { + if (__DEV__) { + markAttrsAccessed() + } + return instance[type][key] + }, has: (instance, key) => key === SetupProxySymbol || key in instance[type], ownKeys: instance => Reflect.ownKeys(instance[type]), // this is necessary for ownKeys to work properly