]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
Merge branch 'main' into edison/fix/12639
authoredison <daiwei521@126.com>
Sat, 7 Jun 2025 00:39:31 +0000 (08:39 +0800)
committerGitHub <noreply@github.com>
Sat, 7 Jun 2025 00:39:31 +0000 (08:39 +0800)
1  2 
packages/runtime-core/__tests__/rendererTemplateRef.spec.ts

index b9e5740d08c33489bfe90043411481a5b8db44e5,7803826e3df2d37d28814bb9588c7a0c574cbce8..cc0a5b5bbf59402ce96224c2e984061ec65b99dd
@@@ -180,87 -179,35 +180,118 @@@ describe('api: template refs', () => 
      expect(el.value).toBe(null)
    })
  
-     expect(refName.value).toBe('b')
 +  // #12639
 +  it('update and unmount child in the same tick', async () => {
 +    const root = nodeOps.createElement('div')
 +    const el = ref(null)
 +    const toggle = ref(true)
 +    const show = ref(true)
 +
 +    const Comp = defineComponent({
 +      emits: ['change'],
 +      props: ['show'],
 +      setup(props, { emit }) {
 +        watch(
 +          () => props.show,
 +          () => {
 +            emit('change')
 +          },
 +        )
 +        return () => h('div', 'hi')
 +      },
 +    })
 +
 +    const App = {
 +      setup() {
 +        return {
 +          refKey: el,
 +        }
 +      },
 +      render() {
 +        return toggle.value
 +          ? h(Comp, {
 +              ref: 'refKey',
 +              show: show.value,
 +              onChange: () => (toggle.value = false),
 +            })
 +          : null
 +      },
 +    }
 +    render(h(App), root)
 +    expect(el.value).not.toBe(null)
 +
 +    show.value = false
 +    await nextTick()
 +    expect(el.value).toBe(null)
 +  })
 +
 +  it('set and change ref in the same tick', async () => {
 +    const root = nodeOps.createElement('div')
 +    const show = ref(false)
 +    const refName = ref('a')
 +
 +    const Child = defineComponent({
 +      setup() {
 +        refName.value = 'b'
 +        return () => {}
 +      },
 +    })
 +
 +    const Comp = {
 +      render() {
 +        return h(Child, {
 +          ref: refName.value,
 +        })
 +      },
 +      updated(this: any) {
 +        expect(this.$refs.a).toBe(null)
 +        expect(this.$refs.b).not.toBe(null)
 +      },
 +    }
 +
 +    const App = {
 +      render() {
 +        return show.value ? h(Comp) : null
 +      },
 +    }
 +
 +    render(h(App), root)
 +    expect(refName.value).toBe('a')
 +
 +    show.value = true
 +    await nextTick()
++    expect(refName.value).toBe('b')  
++  })
++
+   it('unset old ref when new ref is absent', async () => {
+     const root1 = nodeOps.createElement('div')
+     const root2 = nodeOps.createElement('div')
+     const el1 = ref(null)
+     const el2 = ref(null)
+     const toggle = ref(true)
+     const Comp1 = {
+       setup() {
+         return () => (toggle.value ? h('div', { ref: el1 }) : h('div'))
+       },
+     }
+     const Comp2 = {
+       setup() {
+         return () => h('div', { ref: toggle.value ? el2 : undefined })
+       },
+     }
+     render(h(Comp1), root1)
+     render(h(Comp2), root2)
+     expect(el1.value).toBe(root1.children[0])
+     expect(el2.value).toBe(root2.children[0])
+     toggle.value = false
+     await nextTick()
+     expect(el1.value).toBe(null)
+     expect(el2.value).toBe(null)
    })
  
    test('string ref inside slots', async () => {