]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-core): fix regression for $attrs tracking in slots
authorEvan You <yyx990803@gmail.com>
Tue, 16 Apr 2024 13:53:25 +0000 (21:53 +0800)
committerEvan You <yyx990803@gmail.com>
Tue, 16 Apr 2024 13:53:47 +0000 (21:53 +0800)
close #10710

packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts
packages/runtime-core/src/componentPublicInstance.ts

index 79e2867ad699d106834eaf51963a4b410766dcd4..9c985379c1e90d4a459d07b1d5ddf4a28db448c7 100644 (file)
@@ -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: `<slot/>`,
+    }
+    const Child = {
+      components: { GrandChild },
+      template: `<div><GrandChild>{{ $attrs.foo }}</GrandChild></div>`,
+    }
+
+    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('<div foo="1">1</div>')
+
+    obj.value = 2
+    await nextTick()
+    expect(root.innerHTML).toBe('<div foo="2">2</div>')
+  })
 })
index a1b45e4f9cce57f93461a3ea9f825fe3910d3d58..b43accfa0a34650398f0ee7dbcfd3c4cebb83ab9 100644 (file)
@@ -368,9 +368,10 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
     // 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)