From 010b2894507467e4f5524bdddaddbd9449edb5ad Mon Sep 17 00:00:00 2001 From: liulinboyi <814921718@qq.com> Date: Fri, 24 Jun 2022 02:04:19 +0800 Subject: [PATCH 1/2] fix(runtime-core): ref in v-for does not trigger watchEffect --- packages/runtime-core/src/rendererTemplateRef.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime-core/src/rendererTemplateRef.ts b/packages/runtime-core/src/rendererTemplateRef.ts index 1fe432d5019..44ba0b0b861 100644 --- a/packages/runtime-core/src/rendererTemplateRef.ts +++ b/packages/runtime-core/src/rendererTemplateRef.ts @@ -84,7 +84,7 @@ export function setRef( if (_isString || _isRef) { const doSet = () => { if (rawRef.f) { - const existing = _isString ? refs[ref] : ref.value + const existing = _isString ? hasOwn(setupState, ref) ? setupState[ref] : refs[ref] : ref.value if (isUnmount) { isArray(existing) && remove(existing, refValue) } else { From 2f45f44a2aab42a01f8f9e5c0647d42d976d0ed2 Mon Sep 17 00:00:00 2001 From: liulinboyi <814921718@qq.com> Date: Fri, 24 Jun 2022 02:27:03 +0800 Subject: [PATCH 2/2] feat(test): add test for ref in v-for does not trigger watchEffect --- .../__tests__/rendererTemplateRef.spec.ts | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts b/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts index 6a03e7a8eb5..919a1651768 100644 --- a/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts +++ b/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts @@ -9,6 +9,7 @@ import { serializeInner, shallowRef } from '@vue/runtime-test' +import { watchEffect } from '@vue/runtime-core' // reference: https://vue-composition-api-rfc.netlify.com/api.html#template-refs @@ -493,4 +494,61 @@ describe('api: template refs', () => { await nextTick() expect(mapRefs()).toMatchObject(['2', '3', '4']) }) + + test('named ref in v-for with watchEffect', async () => { + const show = ref(true) + const list = reactive([1, 2, 3]) + const listRefs = ref([]) + const check = ref() + + const mapRefs = () => listRefs.value.map(n => serializeInner(n)) + watchEffect(() => (check.value = mapRefs())) + + const App = { + setup() { + return { listRefs } + }, + render() { + return show.value + ? h( + 'ul', + list.map(i => + h( + 'li', + { + ref: 'listRefs', + ref_for: true + }, + i + ) + ) + ) + : null + } + } + const root = nodeOps.createElement('div') + render(h(App), root) + + expect(check.value).toMatchObject([]) + + await nextTick() + expect(check.value).toMatchObject(['1', '2', '3']) + + list.push(4) + await nextTick() + expect(check.value).toMatchObject(['1', '2', '3', '4']) + + list.shift() + await nextTick() + expect(check.value).toMatchObject(['2', '3', '4']) + + show.value = !show.value + await nextTick() + + expect(check.value).toMatchObject([]) + + show.value = !show.value + await nextTick() + expect(check.value).toMatchObject(['2', '3', '4']) + }) })