Skip to content

Commit de4d2e2

Browse files
committed
perf(templateRef): avoid double render when using template ref on v-for
close vuejs#9908
1 parent c3087ff commit de4d2e2

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

packages/runtime-core/src/rendererTemplateRef.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,10 @@ export function setRef(
8181
} else {
8282
const _isString = isString(ref)
8383
const _isRef = isRef(ref)
84+
const isVFor = rawRef.f
8485
if (_isString || _isRef) {
8586
const doSet = () => {
86-
if (rawRef.f) {
87+
if (isVFor) {
8788
const existing = _isString
8889
? hasOwn(setupState, ref)
8990
? setupState[ref]
@@ -118,14 +119,15 @@ export function setRef(
118119
warn('Invalid template ref type:', ref, `(${typeof ref})`)
119120
}
120121
}
121-
if (value) {
122-
// #1789: for non-null values, set them after render
123-
// null values means this is unmount and it should not overwrite another
124-
// ref with the same key
122+
// #9908 ref on v-for mutates the same array for both mount and unmount
123+
// and should be done together
124+
if (isUnmount || isVFor) {
125+
doSet()
126+
} else {
127+
// #1789: set new refs in a post job so that they don't get overwritten
128+
// by unmounting ones.
125129
;(doSet as SchedulerJob).id = -1
126130
queuePostRenderEffect(doSet, parentSuspense)
127-
} else {
128-
doSet()
129131
}
130132
} else if (__DEV__) {
131133
warn('Invalid template ref type:', ref, `(${typeof ref})`)

0 commit comments

Comments
 (0)