diff --git a/packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts b/packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts index 79e2867ad69..9c985379c1e 100644 --- a/packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts +++ b/packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts @@ -20,6 +20,7 @@ import { render, withModifiers, } from '@vue/runtime-dom' +import { createApp } from 'vue' import { PatchFlags } from '@vue/shared' describe('attribute fallthrough', () => { @@ -783,4 +784,31 @@ describe('attribute fallthrough', () => { expect(textBar).toBe('from GrandChild') expect(textFoo).toBe('from Child') }) + + // covers uncaught regression #10710 + it('should track this.$attrs access in slots', async () => { + const GrandChild = { + template: ``, + } + const Child = { + components: { GrandChild }, + template: `
{{ $attrs.foo }}
`, + } + + const obj = ref(1) + const App = { + render() { + return h(Child, { foo: obj.value }) + }, + } + + const root = document.createElement('div') + createApp(App).mount(root) + + expect(root.innerHTML).toBe('
1
') + + obj.value = 2 + await nextTick() + expect(root.innerHTML).toBe('
2
') + }) }) diff --git a/packages/runtime-core/src/componentPublicInstance.ts b/packages/runtime-core/src/componentPublicInstance.ts index a1b45e4f9cc..b43accfa0a3 100644 --- a/packages/runtime-core/src/componentPublicInstance.ts +++ b/packages/runtime-core/src/componentPublicInstance.ts @@ -368,9 +368,10 @@ export const PublicInstanceProxyHandlers: ProxyHandler = { // public $xxx properties if (publicGetter) { if (key === '$attrs') { - track(instance, TrackOpTypes.GET, key) + track(instance.attrs, TrackOpTypes.GET, '') __DEV__ && markAttrsAccessed() } else if (__DEV__ && key === '$slots') { + // for HMR only track(instance, TrackOpTypes.GET, key) } return publicGetter(instance)