From 80fdddb79d432dbc0724b2049b488dceb8f38c0e Mon Sep 17 00:00:00 2001 From: baiwusanyu <740132583@qq.com> Date: Wed, 21 Sep 2022 23:05:33 +0800 Subject: [PATCH 1/5] fix(runtime-core):v-for ref behaves differently under prod and dev #6697 --- packages/runtime-core/src/rendererTemplateRef.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/runtime-core/src/rendererTemplateRef.ts b/packages/runtime-core/src/rendererTemplateRef.ts index 1fe432d5019..63a111f8f15 100644 --- a/packages/runtime-core/src/rendererTemplateRef.ts +++ b/packages/runtime-core/src/rendererTemplateRef.ts @@ -12,7 +12,7 @@ import { import { isAsyncWrapper } from './apiAsyncComponent' import { getExposeProxy } from './component' import { warn } from './warning' -import { isRef } from '@vue/reactivity' +import {isRef, reactive} from '@vue/reactivity' import { callWithErrorHandling, ErrorCodes } from './errorHandling' import { SchedulerJob } from './scheduler' import { queuePostRenderEffect } from './renderer' @@ -61,7 +61,7 @@ export function setRef( return } const oldRef = oldRawRef && (oldRawRef as VNodeNormalizedRefAtom).r - const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs + const refs = owner.refs === EMPTY_OBJ ? (owner.refs = reactive({})) : owner.refs const setupState = owner.setupState // dynamic ref changed. unset old ref From 6c4b72a63a083945558fb04625f07ec070f3df2a Mon Sep 17 00:00:00 2001 From: chenzhihui <18281682921@qqcom> Date: Mon, 26 Sep 2022 09:57:09 +0800 Subject: [PATCH 2/5] fix(runtime-core):add unit test #6697 --- .../__tests__/rendererTemplateRef.spec.ts | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts b/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts index 6a03e7a8eb5..079928a5a8b 100644 --- a/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts +++ b/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts @@ -493,4 +493,48 @@ describe('api: template refs', () => { await nextTick() expect(mapRefs()).toMatchObject(['2', '3', '4']) }) + + // #6697 v-for ref behaves differently under production and development + test('named ref in v-for , should be responsive when rendering', async () => { + const list = ref([1, 2, 3]) + const listRefs = ref([]) + const App = { + setup() { + return { listRefs } + }, + render() { + return h( + 'div', + null, + [ + h('div',null,String(listRefs.value)), + h( + 'ul', + list.value.map(i => + h( + 'li', + { + ref: 'listRefs', + ref_for: true + }, + i + ) + ) + ) + ] + ) + } + } + const root = nodeOps.createElement('div') + render(h(App), root) + + await nextTick() + expect(String(listRefs.value)).toBe('[object Object],[object Object],[object Object]') + expect(serializeInner(root)).toBe('
[object Object],[object Object],[object Object]
') + + list.value.splice(0,1); + await nextTick() + expect(String(listRefs.value)).toBe('[object Object],[object Object]') + expect(serializeInner(root)).toBe('
[object Object],[object Object]
') + }) }) From b6b2abf3877b31ba9d760b15a73bc34d64db450e Mon Sep 17 00:00:00 2001 From: baiwusanyu <740132583@qq.com> Date: Tue, 4 Oct 2022 02:08:51 +0800 Subject: [PATCH 3/5] fix(runtime-core):format code #6697 --- .../__tests__/rendererTemplateRef.spec.ts | 48 ++++++++++--------- .../runtime-core/src/rendererTemplateRef.ts | 5 +- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts b/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts index 079928a5a8b..668391c9185 100644 --- a/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts +++ b/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts @@ -503,38 +503,40 @@ describe('api: template refs', () => { return { listRefs } }, render() { - return h( - 'div', - null, - [ - h('div',null,String(listRefs.value)), - h( - 'ul', - list.value.map(i => - h( - 'li', - { - ref: 'listRefs', - ref_for: true - }, - i - ) - ) - ) - ] + return h('div', null, [ + h('div', null, String(listRefs.value)), + h( + 'ul', + list.value.map(i => + h( + 'li', + { + ref: 'listRefs', + ref_for: true + }, + i + ) ) + ) + ]) } } const root = nodeOps.createElement('div') render(h(App), root) await nextTick() - expect(String(listRefs.value)).toBe('[object Object],[object Object],[object Object]') - expect(serializeInner(root)).toBe('
[object Object],[object Object],[object Object]
') + expect(String(listRefs.value)).toBe( + '[object Object],[object Object],[object Object]' + ) + expect(serializeInner(root)).toBe( + '
[object Object],[object Object],[object Object]
' + ) - list.value.splice(0,1); + list.value.splice(0, 1) await nextTick() expect(String(listRefs.value)).toBe('[object Object],[object Object]') - expect(serializeInner(root)).toBe('
[object Object],[object Object]
') + expect(serializeInner(root)).toBe( + '
[object Object],[object Object]
' + ) }) }) diff --git a/packages/runtime-core/src/rendererTemplateRef.ts b/packages/runtime-core/src/rendererTemplateRef.ts index 63a111f8f15..443606b6312 100644 --- a/packages/runtime-core/src/rendererTemplateRef.ts +++ b/packages/runtime-core/src/rendererTemplateRef.ts @@ -12,7 +12,7 @@ import { import { isAsyncWrapper } from './apiAsyncComponent' import { getExposeProxy } from './component' import { warn } from './warning' -import {isRef, reactive} from '@vue/reactivity' +import { isRef, reactive } from '@vue/reactivity' import { callWithErrorHandling, ErrorCodes } from './errorHandling' import { SchedulerJob } from './scheduler' import { queuePostRenderEffect } from './renderer' @@ -61,7 +61,8 @@ export function setRef( return } const oldRef = oldRawRef && (oldRawRef as VNodeNormalizedRefAtom).r - const refs = owner.refs === EMPTY_OBJ ? (owner.refs = reactive({})) : owner.refs + const refs = + owner.refs === EMPTY_OBJ ? (owner.refs = reactive({})) : owner.refs const setupState = owner.setupState // dynamic ref changed. unset old ref From 13b9b8b45d2fc9758781a75efb6c4a5e3e18a5b1 Mon Sep 17 00:00:00 2001 From: chenzhihui <18281682921@qqcom> Date: Sat, 8 Oct 2022 14:06:05 +0800 Subject: [PATCH 4/5] fix(runtime-core):Modification method --- packages/runtime-core/src/rendererTemplateRef.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/runtime-core/src/rendererTemplateRef.ts b/packages/runtime-core/src/rendererTemplateRef.ts index 443606b6312..9dfcc00b340 100644 --- a/packages/runtime-core/src/rendererTemplateRef.ts +++ b/packages/runtime-core/src/rendererTemplateRef.ts @@ -12,7 +12,7 @@ import { import { isAsyncWrapper } from './apiAsyncComponent' import { getExposeProxy } from './component' import { warn } from './warning' -import { isRef, reactive } from '@vue/reactivity' +import { isRef } from '@vue/reactivity' import { callWithErrorHandling, ErrorCodes } from './errorHandling' import { SchedulerJob } from './scheduler' import { queuePostRenderEffect } from './renderer' @@ -61,8 +61,7 @@ export function setRef( return } const oldRef = oldRawRef && (oldRawRef as VNodeNormalizedRefAtom).r - const refs = - owner.refs === EMPTY_OBJ ? (owner.refs = reactive({})) : owner.refs + const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs const setupState = owner.setupState // dynamic ref changed. unset old ref @@ -94,6 +93,11 @@ export function setRef( refs[ref] = [refValue] if (hasOwn(setupState, ref)) { setupState[ref] = refs[ref] + // #6697 + // Only valid in composition Api: + // setupState is assigned to refs to ensure + // that the variable 'existing' can be used as a template dependency + refs[ref] = setupState[ref] } } else { ref.value = [refValue] From 02efd1097e8d221748695989d50e345f24b8c4ad Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 14 Oct 2022 05:09:11 -0400 Subject: [PATCH 5/5] Update rendererTemplateRef.ts --- packages/runtime-core/src/rendererTemplateRef.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/runtime-core/src/rendererTemplateRef.ts b/packages/runtime-core/src/rendererTemplateRef.ts index 9dfcc00b340..30f96228d1f 100644 --- a/packages/runtime-core/src/rendererTemplateRef.ts +++ b/packages/runtime-core/src/rendererTemplateRef.ts @@ -84,7 +84,11 @@ 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 { @@ -93,11 +97,6 @@ export function setRef( refs[ref] = [refValue] if (hasOwn(setupState, ref)) { setupState[ref] = refs[ref] - // #6697 - // Only valid in composition Api: - // setupState is assigned to refs to ensure - // that the variable 'existing' can be used as a template dependency - refs[ref] = setupState[ref] } } else { ref.value = [refValue]