fix(runtime-core/template-ref): template ref used in the same template should trigger update
fix #1505
This commit is contained in:
parent
64e2f46436
commit
36b6b4f022
@ -5,7 +5,8 @@ import {
|
|||||||
render,
|
render,
|
||||||
nextTick,
|
nextTick,
|
||||||
defineComponent,
|
defineComponent,
|
||||||
reactive
|
reactive,
|
||||||
|
serializeInner
|
||||||
} from '@vue/runtime-test'
|
} from '@vue/runtime-test'
|
||||||
|
|
||||||
// reference: https://vue-composition-api-rfc.netlify.com/api.html#template-refs
|
// reference: https://vue-composition-api-rfc.netlify.com/api.html#template-refs
|
||||||
@ -246,4 +247,25 @@ describe('api: template refs', () => {
|
|||||||
expect(refKey2.value).toBe(root.children[2])
|
expect(refKey2.value).toBe(root.children[2])
|
||||||
expect(refKey3.value).toBe(root.children[3])
|
expect(refKey3.value).toBe(root.children[3])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// #1505
|
||||||
|
test('reactive template ref in the same template', async () => {
|
||||||
|
const Comp = {
|
||||||
|
setup() {
|
||||||
|
const el = ref()
|
||||||
|
return { el }
|
||||||
|
},
|
||||||
|
render(this: any) {
|
||||||
|
return h('div', { id: 'foo', ref: 'el' }, this.el && this.el.props.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
render(h(Comp), root)
|
||||||
|
// ref not ready on first render, but should queue an update immediately
|
||||||
|
expect(serializeInner(root)).toBe(`<div id="foo"></div>`)
|
||||||
|
await nextTick()
|
||||||
|
// ref should be updated
|
||||||
|
expect(serializeInner(root)).toBe(`<div id="foo">foo</div>`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -227,7 +227,7 @@ export function createHydrationFunctions(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ref != null && parentComponent) {
|
if (ref != null && parentComponent) {
|
||||||
setRef(ref, null, parentComponent, vnode)
|
setRef(ref, null, parentComponent, parentSuspense, vnode)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nextNode
|
return nextNode
|
||||||
|
@ -275,7 +275,8 @@ export const queuePostRenderEffect = __FEATURE_SUSPENSE__
|
|||||||
export const setRef = (
|
export const setRef = (
|
||||||
rawRef: VNodeNormalizedRef,
|
rawRef: VNodeNormalizedRef,
|
||||||
oldRawRef: VNodeNormalizedRef | null,
|
oldRawRef: VNodeNormalizedRef | null,
|
||||||
parent: ComponentInternalInstance,
|
parentComponent: ComponentInternalInstance,
|
||||||
|
parentSuspense: SuspenseBoundary | null,
|
||||||
vnode: VNode | null
|
vnode: VNode | null
|
||||||
) => {
|
) => {
|
||||||
let value: ComponentPublicInstance | RendererNode | null
|
let value: ComponentPublicInstance | RendererNode | null
|
||||||
@ -306,7 +307,9 @@ export const setRef = (
|
|||||||
if (isString(oldRef)) {
|
if (isString(oldRef)) {
|
||||||
refs[oldRef] = null
|
refs[oldRef] = null
|
||||||
if (hasOwn(setupState, oldRef)) {
|
if (hasOwn(setupState, oldRef)) {
|
||||||
setupState[oldRef] = null
|
queuePostRenderEffect(() => {
|
||||||
|
setupState[oldRef] = null
|
||||||
|
}, parentSuspense)
|
||||||
}
|
}
|
||||||
} else if (isRef(oldRef)) {
|
} else if (isRef(oldRef)) {
|
||||||
oldRef.value = null
|
oldRef.value = null
|
||||||
@ -316,12 +319,17 @@ export const setRef = (
|
|||||||
if (isString(ref)) {
|
if (isString(ref)) {
|
||||||
refs[ref] = value
|
refs[ref] = value
|
||||||
if (hasOwn(setupState, ref)) {
|
if (hasOwn(setupState, ref)) {
|
||||||
setupState[ref] = value
|
queuePostRenderEffect(() => {
|
||||||
|
setupState[ref] = value
|
||||||
|
}, parentSuspense)
|
||||||
}
|
}
|
||||||
} else if (isRef(ref)) {
|
} else if (isRef(ref)) {
|
||||||
ref.value = value
|
ref.value = value
|
||||||
} else if (isFunction(ref)) {
|
} else if (isFunction(ref)) {
|
||||||
callWithErrorHandling(ref, parent, ErrorCodes.FUNCTION_REF, [value, refs])
|
callWithErrorHandling(ref, parentComponent, ErrorCodes.FUNCTION_REF, [
|
||||||
|
value,
|
||||||
|
refs
|
||||||
|
])
|
||||||
} else if (__DEV__) {
|
} else if (__DEV__) {
|
||||||
warn('Invalid template ref type:', value, `(${typeof value})`)
|
warn('Invalid template ref type:', value, `(${typeof value})`)
|
||||||
}
|
}
|
||||||
@ -497,7 +505,7 @@ function baseCreateRenderer(
|
|||||||
|
|
||||||
// set ref
|
// set ref
|
||||||
if (ref != null && parentComponent) {
|
if (ref != null && parentComponent) {
|
||||||
setRef(ref, n1 && n1.ref, parentComponent, n2)
|
setRef(ref, n1 && n1.ref, parentComponent, parentSuspense, n2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1868,7 +1876,7 @@ function baseCreateRenderer(
|
|||||||
} = vnode
|
} = vnode
|
||||||
// unset ref
|
// unset ref
|
||||||
if (ref != null && parentComponent) {
|
if (ref != null && parentComponent) {
|
||||||
setRef(ref, null, parentComponent, null)
|
setRef(ref, null, parentComponent, parentSuspense, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE) {
|
if (shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user