fix(ssr): should set ref on hydration
This commit is contained in:
@@ -47,7 +47,6 @@ import { effect, stop, ReactiveEffectOptions, isRef } from '@vue/reactivity'
|
||||
import { updateProps } from './componentProps'
|
||||
import { updateSlots } from './componentSlots'
|
||||
import { pushWarningContext, popWarningContext, warn } from './warning'
|
||||
import { ComponentPublicInstance } from './componentProxy'
|
||||
import { createAppAPI, CreateAppFunction } from './apiCreateApp'
|
||||
import {
|
||||
SuspenseBoundary,
|
||||
@@ -271,6 +270,55 @@ export const queuePostRenderEffect = __FEATURE_SUSPENSE__
|
||||
? queueEffectWithSuspense
|
||||
: queuePostFlushCb
|
||||
|
||||
export const setRef = (
|
||||
rawRef: VNodeNormalizedRef,
|
||||
oldRawRef: VNodeNormalizedRef | null,
|
||||
parent: ComponentInternalInstance,
|
||||
vnode: VNode | null
|
||||
) => {
|
||||
const value = vnode
|
||||
? vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT
|
||||
? vnode.component!.proxy
|
||||
: vnode.el
|
||||
: null
|
||||
const [owner, ref] = rawRef
|
||||
if (__DEV__ && !owner) {
|
||||
warn(
|
||||
`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
|
||||
`A vnode with ref must be created inside the render function.`
|
||||
)
|
||||
return
|
||||
}
|
||||
const oldRef = oldRawRef && oldRawRef[1]
|
||||
const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs
|
||||
const setupState = owner.setupState
|
||||
|
||||
// unset old ref
|
||||
if (oldRef != null && oldRef !== ref) {
|
||||
if (isString(oldRef)) {
|
||||
refs[oldRef] = null
|
||||
if (hasOwn(setupState, oldRef)) {
|
||||
setupState[oldRef] = null
|
||||
}
|
||||
} else if (isRef(oldRef)) {
|
||||
oldRef.value = null
|
||||
}
|
||||
}
|
||||
|
||||
if (isString(ref)) {
|
||||
refs[ref] = value
|
||||
if (hasOwn(setupState, ref)) {
|
||||
setupState[ref] = value
|
||||
}
|
||||
} else if (isRef(ref)) {
|
||||
ref.value = value
|
||||
} else if (isFunction(ref)) {
|
||||
callWithErrorHandling(ref, parent, ErrorCodes.FUNCTION_REF, [value, refs])
|
||||
} else if (__DEV__) {
|
||||
warn('Invalid template ref type:', value, `(${typeof value})`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The createRenderer function accepts two generic arguments:
|
||||
* HostNode and HostElement, corresponding to Node and Element types in the
|
||||
@@ -440,9 +488,7 @@ function baseCreateRenderer(
|
||||
|
||||
// set ref
|
||||
if (ref != null && parentComponent) {
|
||||
const refValue =
|
||||
shapeFlag & ShapeFlags.STATEFUL_COMPONENT ? n2.component!.proxy : n2.el
|
||||
setRef(ref, n1 && n1.ref, parentComponent, refValue)
|
||||
setRef(ref, n1 && n1.ref, parentComponent, n2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1984,50 +2030,6 @@ function baseCreateRenderer(
|
||||
return hostNextSibling((vnode.anchor || vnode.el)!)
|
||||
}
|
||||
|
||||
const setRef = (
|
||||
rawRef: VNodeNormalizedRef,
|
||||
oldRawRef: VNodeNormalizedRef | null,
|
||||
parent: ComponentInternalInstance,
|
||||
value: RendererNode | ComponentPublicInstance | null
|
||||
) => {
|
||||
const [owner, ref] = rawRef
|
||||
if (__DEV__ && !owner) {
|
||||
warn(
|
||||
`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
|
||||
`A vnode with ref must be created inside the render function.`
|
||||
)
|
||||
return
|
||||
}
|
||||
const oldRef = oldRawRef && oldRawRef[1]
|
||||
const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs
|
||||
const setupState = owner.setupState
|
||||
|
||||
// unset old ref
|
||||
if (oldRef != null && oldRef !== ref) {
|
||||
if (isString(oldRef)) {
|
||||
refs[oldRef] = null
|
||||
if (hasOwn(setupState, oldRef)) {
|
||||
setupState[oldRef] = null
|
||||
}
|
||||
} else if (isRef(oldRef)) {
|
||||
oldRef.value = null
|
||||
}
|
||||
}
|
||||
|
||||
if (isString(ref)) {
|
||||
refs[ref] = value
|
||||
if (hasOwn(setupState, ref)) {
|
||||
setupState[ref] = value
|
||||
}
|
||||
} else if (isRef(ref)) {
|
||||
ref.value = value
|
||||
} else if (isFunction(ref)) {
|
||||
callWithErrorHandling(ref, parent, ErrorCodes.FUNCTION_REF, [value, refs])
|
||||
} else if (__DEV__) {
|
||||
warn('Invalid template ref type:', value, `(${typeof value})`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* #1156
|
||||
* When a component is HMR-enabled, we need to make sure that all static nodes
|
||||
|
||||
Reference in New Issue
Block a user