]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
perf(templateRef): avoid double render when using template ref on v-for
authorEvan You <yyx990803@gmail.com>
Thu, 18 Jan 2024 13:25:10 +0000 (21:25 +0800)
committerEvan You <yyx990803@gmail.com>
Thu, 18 Jan 2024 13:25:10 +0000 (21:25 +0800)
close #9908

packages/runtime-core/src/rendererTemplateRef.ts

index b652edeac4c96a3dea6ba02a6ccdbfc2128e9023..7f991bc9f5f919548ada395bf16f8d7e37a0cf3f 100644 (file)
@@ -81,9 +81,10 @@ export function setRef(
   } else {
     const _isString = isString(ref)
     const _isRef = isRef(ref)
+    const isVFor = rawRef.f
     if (_isString || _isRef) {
       const doSet = () => {
-        if (rawRef.f) {
+        if (isVFor) {
           const existing = _isString
             ? hasOwn(setupState, ref)
               ? setupState[ref]
@@ -118,14 +119,15 @@ export function setRef(
           warn('Invalid template ref type:', ref, `(${typeof ref})`)
         }
       }
-      if (value) {
-        // #1789: for non-null values, set them after render
-        // null values means this is unmount and it should not overwrite another
-        // ref with the same key
+      // #9908 ref on v-for mutates the same array for both mount and unmount
+      // and should be done together
+      if (isUnmount || isVFor) {
+        doSet()
+      } else {
+        // #1789: set new refs in a post job so that they don't get overwritten
+        // by unmounting ones.
         ;(doSet as SchedulerJob).id = -1
         queuePostRenderEffect(doSet, parentSuspense)
-      } else {
-        doSet()
       }
     } else if (__DEV__) {
       warn('Invalid template ref type:', ref, `(${typeof ref})`)