2
0
Эх сурвалжийг харах

fix(templateRef): don't update setup ref for useTemplateRef key (#14444)

sync https://github.com/vuejs/core/pull/12756/changes
edison 2 сар өмнө
parent
commit
ccd1ddf87d

+ 1 - 1
packages/runtime-core/src/index.ts

@@ -687,4 +687,4 @@ export {
 /**
  * @internal
  */
-export { knownTemplateRefs } from './helpers/useTemplateRef'
+export { knownTemplateRefs, isTemplateRefKey } from './helpers/useTemplateRef'

+ 45 - 0
packages/runtime-vapor/__tests__/dom/templateRef.spec.ts

@@ -938,6 +938,51 @@ describe('api: template ref', () => {
     }
   })
 
+  // #12749
+  test(`don't update setup ref for useTemplateRef key`, () => {
+    let foo: ShallowRef
+    let bar: ReturnType<typeof ref>
+    const { host } = define({
+      setup() {
+        foo = useTemplateRef('bar')
+        bar = ref(null)
+        return { bar }
+      },
+      render() {
+        const n0 = template('<div></div>')() as Element
+        createTemplateRefSetter()(n0, 'bar')
+        return n0
+      },
+    }).render()
+
+    expect(bar!.value).toBe(null)
+    expect(foo!.value).toBe(host.children[0])
+  })
+
+  test(`don't update setup ref for useTemplateRef key (compiled in prod mode)`, () => {
+    __DEV__ = false
+    try {
+      let foo: ReturnType<typeof ref>
+      let fooRef: ShallowRef
+      const { host } = define({
+        setup() {
+          foo = ref('hello')
+          fooRef = useTemplateRef('foo')
+        },
+        render() {
+          const n0 = template('<div></div>')() as Element
+          createTemplateRefSetter()(n0, foo!, false, 'foo')
+          return n0
+        },
+      }).render()
+
+      expect(foo!.value).toBe('hello')
+      expect(fooRef!.value).toBe(host.children[0])
+    } finally {
+      __DEV__ = true
+    }
+  })
+
   // TODO: can not reproduce in Vapor
   // // #2078
   // test('handling multiple merged refs', async () => {

+ 12 - 5
packages/runtime-vapor/src/apiTemplateRef.ts

@@ -11,6 +11,7 @@ import {
   callWithErrorHandling,
   createCanSetSetupRefChecker,
   isAsyncWrapper,
+  isTemplateRefKey,
   knownTemplateRefs,
   queuePostFlushCb,
   warn,
@@ -104,8 +105,14 @@ export function setRef(
     ? createCanSetSetupRefChecker(setupState, refs)
     : NO
 
-  const canSetRef = (ref: NodeRef) => {
-    return !__DEV__ || !knownTemplateRefs.has(ref as any)
+  const canSetRef = (ref: NodeRef, key?: string) => {
+    if (__DEV__ && knownTemplateRefs.has(ref as any)) {
+      return false
+    }
+    if (key && isTemplateRefKey(refs, key)) {
+      return false
+    }
+    return true
   }
 
   // dynamic ref changed. unset old ref
@@ -158,7 +165,7 @@ export function setRef(
                 existing = setupState[ref]
               }
             } else {
-              if (canSetRef(ref)) ref.value = existing
+              if (canSetRef(ref, refKey)) ref.value = existing
               if (refKey) refs[refKey] = existing
             }
           } else if (!existing.includes(refValue)) {
@@ -170,7 +177,7 @@ export function setRef(
             setupState[ref] = refValue
           }
         } else if (_isRef) {
-          if (canSetRef(ref)) ref.value = refValue
+          if (canSetRef(ref, refKey)) ref.value = refValue
           if (refKey) refs[refKey] = refValue
         } else if (__DEV__) {
           warn('Invalid template ref type:', ref, `(${typeof ref})`)
@@ -188,7 +195,7 @@ export function setRef(
               setupState[ref] = null
             }
           } else if (_isRef) {
-            if (canSetRef(ref)) ref.value = null
+            if (canSetRef(ref, refKey)) ref.value = null
             if (refKey) refs[refKey] = null
           }
         })