Explorar el Código

fix(keep-alive): fix activated hook invocation on nested components (#1743)

fix #1742
zhangzhonghe hace 5 años
padre
commit
233d191d0d

+ 30 - 0
packages/runtime-core/__tests__/components/KeepAlive.spec.ts

@@ -165,6 +165,36 @@ describe('KeepAlive', () => {
     assertHookCalls(two, [1, 1, 2, 2, 0])
   })
 
+  // #1742
+  test('should call lifecycle hooks on nested components when root component no hooks', async () => {
+    const two = {
+      name: 'two',
+      data: () => ({ msg: 'two' }),
+      render(this: any) {
+        return h('div', this.msg)
+      },
+      activated: jest.fn()
+    }
+    const one = {
+      name: 'one',
+      data: () => ({ msg: 'one' }),
+      render(this: any) {
+        return h(two)
+      }
+    }
+
+    const toggle = ref(true)
+    const App = {
+      render() {
+        return h(KeepAlive, () => (toggle.value ? h(one) : null))
+      }
+    }
+    render(h(App), root)
+
+    expect(serializeInner(root)).toBe(`<div>two</div>`)
+    expect(two.activated).toHaveBeenCalledTimes(1)
+  })
+
   test('should call correct hooks for nested keep-alive', async () => {
     const toggle2 = ref(true)
     one.render = () => h(KeepAlive, () => (toggle2.value ? h(two) : null))

+ 4 - 1
packages/runtime-core/src/renderer.ts

@@ -1265,7 +1265,7 @@ function baseCreateRenderer(
       if (!instance.isMounted) {
         let vnodeHook: VNodeHook | null | undefined
         const { el, props } = initialVNode
-        const { bm, m, a, parent } = instance
+        const { bm, m, parent } = instance
         if (__DEV__) {
           startMeasure(instance, `render`)
         }
@@ -1324,6 +1324,9 @@ function baseCreateRenderer(
           }, parentSuspense)
         }
         // activated hook for keep-alive roots.
+        // #1742 activated hook must be accessed after first render
+        // since the hook may be injected by a child keep-alive
+        const { a } = instance
         if (
           a &&
           initialVNode.shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE