parent
36ae23d27e
commit
ff0c810300
@ -118,7 +118,6 @@ export interface RendererOptions<
|
|||||||
parentSuspense?: SuspenseBoundary | null,
|
parentSuspense?: SuspenseBoundary | null,
|
||||||
unmountChildren?: UnmountChildrenFn
|
unmountChildren?: UnmountChildrenFn
|
||||||
): void
|
): void
|
||||||
forcePatchProp?(el: HostElement, key: string): boolean
|
|
||||||
insert(el: HostNode, parent: HostElement, anchor?: HostNode | null): void
|
insert(el: HostNode, parent: HostElement, anchor?: HostNode | null): void
|
||||||
remove(el: HostNode): void
|
remove(el: HostNode): void
|
||||||
createElement(
|
createElement(
|
||||||
@ -288,99 +287,6 @@ export const queuePostRenderEffect = __FEATURE_SUSPENSE__
|
|||||||
? queueEffectWithSuspense
|
? queueEffectWithSuspense
|
||||||
: queuePostFlushCb
|
: queuePostFlushCb
|
||||||
|
|
||||||
export const setRef = (
|
|
||||||
rawRef: VNodeNormalizedRef,
|
|
||||||
oldRawRef: VNodeNormalizedRef | null,
|
|
||||||
parentSuspense: SuspenseBoundary | null,
|
|
||||||
vnode: VNode,
|
|
||||||
isUnmount = false
|
|
||||||
) => {
|
|
||||||
if (isArray(rawRef)) {
|
|
||||||
rawRef.forEach((r, i) =>
|
|
||||||
setRef(
|
|
||||||
r,
|
|
||||||
oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef),
|
|
||||||
parentSuspense,
|
|
||||||
vnode,
|
|
||||||
isUnmount
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isAsyncWrapper(vnode) && !isUnmount) {
|
|
||||||
// when mounting async components, nothing needs to be done,
|
|
||||||
// because the template ref is forwarded to inner component
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const refValue =
|
|
||||||
vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT
|
|
||||||
? getExposeProxy(vnode.component!) || vnode.component!.proxy
|
|
||||||
: vnode.el
|
|
||||||
const value = isUnmount ? null : refValue
|
|
||||||
|
|
||||||
const { i: owner, r: 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 as VNodeNormalizedRefAtom).r
|
|
||||||
const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs
|
|
||||||
const setupState = owner.setupState
|
|
||||||
|
|
||||||
// dynamic ref changed. 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)) {
|
|
||||||
const doSet = () => {
|
|
||||||
if (__COMPAT__ && isCompatEnabled(DeprecationTypes.V_FOR_REF, owner)) {
|
|
||||||
registerLegacyRef(refs, ref, refValue, owner, rawRef.f, isUnmount)
|
|
||||||
} else {
|
|
||||||
refs[ref] = value
|
|
||||||
}
|
|
||||||
if (hasOwn(setupState, ref)) {
|
|
||||||
setupState[ref] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// #1789: for non-null values, set them after render
|
|
||||||
// null values means this is unmount and it should not overwrite another
|
|
||||||
// ref with the same key
|
|
||||||
if (value) {
|
|
||||||
;(doSet as SchedulerJob).id = -1
|
|
||||||
queuePostRenderEffect(doSet, parentSuspense)
|
|
||||||
} else {
|
|
||||||
doSet()
|
|
||||||
}
|
|
||||||
} else if (isRef(ref)) {
|
|
||||||
const doSet = () => {
|
|
||||||
ref.value = value
|
|
||||||
}
|
|
||||||
if (value) {
|
|
||||||
;(doSet as SchedulerJob).id = -1
|
|
||||||
queuePostRenderEffect(doSet, parentSuspense)
|
|
||||||
} else {
|
|
||||||
doSet()
|
|
||||||
}
|
|
||||||
} else if (isFunction(ref)) {
|
|
||||||
callWithErrorHandling(ref, owner, ErrorCodes.FUNCTION_REF, [value, refs])
|
|
||||||
} else if (__DEV__) {
|
|
||||||
warn('Invalid template ref type:', value, `(${typeof value})`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The createRenderer function accepts two generic arguments:
|
* The createRenderer function accepts two generic arguments:
|
||||||
* HostNode and HostElement, corresponding to Node and Element types in the
|
* HostNode and HostElement, corresponding to Node and Element types in the
|
||||||
@ -444,7 +350,6 @@ function baseCreateRenderer(
|
|||||||
insert: hostInsert,
|
insert: hostInsert,
|
||||||
remove: hostRemove,
|
remove: hostRemove,
|
||||||
patchProp: hostPatchProp,
|
patchProp: hostPatchProp,
|
||||||
forcePatchProp: hostForcePatchProp,
|
|
||||||
createElement: hostCreateElement,
|
createElement: hostCreateElement,
|
||||||
createText: hostCreateText,
|
createText: hostCreateText,
|
||||||
createComment: hostCreateComment,
|
createComment: hostCreateComment,
|
||||||
@ -767,7 +672,7 @@ function baseCreateRenderer(
|
|||||||
// props
|
// props
|
||||||
if (props) {
|
if (props) {
|
||||||
for (const key in props) {
|
for (const key in props) {
|
||||||
if (!isReservedProp(key)) {
|
if (key !== 'value' && !isReservedProp(key)) {
|
||||||
hostPatchProp(
|
hostPatchProp(
|
||||||
el,
|
el,
|
||||||
key,
|
key,
|
||||||
@ -781,6 +686,18 @@ function baseCreateRenderer(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Special case for setting value on DOM elements:
|
||||||
|
* - it can be order-sensitive (e.g. should be set *after* min/max, #2325, #4024)
|
||||||
|
* - it needs to be forced (#1471)
|
||||||
|
* #2353 proposes adding another renderer option to configure this, but
|
||||||
|
* the properties affects are so finite it is worth special casing it
|
||||||
|
* here to reduce the complexity. (Special casing it also should not
|
||||||
|
* affect non-DOM renderers)
|
||||||
|
*/
|
||||||
|
if ('value' in props) {
|
||||||
|
hostPatchProp(el, 'value', null, props.value)
|
||||||
|
}
|
||||||
if ((vnodeHook = props.onVnodeBeforeMount)) {
|
if ((vnodeHook = props.onVnodeBeforeMount)) {
|
||||||
invokeVNodeHook(vnodeHook, parentComponent, vnode)
|
invokeVNodeHook(vnodeHook, parentComponent, vnode)
|
||||||
}
|
}
|
||||||
@ -967,10 +884,8 @@ function baseCreateRenderer(
|
|||||||
const key = propsToUpdate[i]
|
const key = propsToUpdate[i]
|
||||||
const prev = oldProps[key]
|
const prev = oldProps[key]
|
||||||
const next = newProps[key]
|
const next = newProps[key]
|
||||||
if (
|
// #1471 force patch value
|
||||||
next !== prev ||
|
if (next !== prev || key === 'value') {
|
||||||
(hostForcePatchProp && hostForcePatchProp(el, key))
|
|
||||||
) {
|
|
||||||
hostPatchProp(
|
hostPatchProp(
|
||||||
el,
|
el,
|
||||||
key,
|
key,
|
||||||
@ -1104,10 +1019,8 @@ function baseCreateRenderer(
|
|||||||
if (isReservedProp(key)) continue
|
if (isReservedProp(key)) continue
|
||||||
const next = newProps[key]
|
const next = newProps[key]
|
||||||
const prev = oldProps[key]
|
const prev = oldProps[key]
|
||||||
if (
|
// defer patching value
|
||||||
next !== prev ||
|
if (next !== prev && key !== 'value') {
|
||||||
(hostForcePatchProp && hostForcePatchProp(el, key))
|
|
||||||
) {
|
|
||||||
hostPatchProp(
|
hostPatchProp(
|
||||||
el,
|
el,
|
||||||
key,
|
key,
|
||||||
@ -1138,6 +1051,9 @@ function baseCreateRenderer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ('value' in newProps) {
|
||||||
|
hostPatchProp(el, 'value', oldProps.value, newProps.value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2418,6 +2334,99 @@ function baseCreateRenderer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setRef(
|
||||||
|
rawRef: VNodeNormalizedRef,
|
||||||
|
oldRawRef: VNodeNormalizedRef | null,
|
||||||
|
parentSuspense: SuspenseBoundary | null,
|
||||||
|
vnode: VNode,
|
||||||
|
isUnmount = false
|
||||||
|
) {
|
||||||
|
if (isArray(rawRef)) {
|
||||||
|
rawRef.forEach((r, i) =>
|
||||||
|
setRef(
|
||||||
|
r,
|
||||||
|
oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef),
|
||||||
|
parentSuspense,
|
||||||
|
vnode,
|
||||||
|
isUnmount
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAsyncWrapper(vnode) && !isUnmount) {
|
||||||
|
// when mounting async components, nothing needs to be done,
|
||||||
|
// because the template ref is forwarded to inner component
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const refValue =
|
||||||
|
vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT
|
||||||
|
? getExposeProxy(vnode.component!) || vnode.component!.proxy
|
||||||
|
: vnode.el
|
||||||
|
const value = isUnmount ? null : refValue
|
||||||
|
|
||||||
|
const { i: owner, r: 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 as VNodeNormalizedRefAtom).r
|
||||||
|
const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs
|
||||||
|
const setupState = owner.setupState
|
||||||
|
|
||||||
|
// dynamic ref changed. 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)) {
|
||||||
|
const doSet = () => {
|
||||||
|
if (__COMPAT__ && isCompatEnabled(DeprecationTypes.V_FOR_REF, owner)) {
|
||||||
|
registerLegacyRef(refs, ref, refValue, owner, rawRef.f, isUnmount)
|
||||||
|
} else {
|
||||||
|
refs[ref] = value
|
||||||
|
}
|
||||||
|
if (hasOwn(setupState, ref)) {
|
||||||
|
setupState[ref] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// #1789: for non-null values, set them after render
|
||||||
|
// null values means this is unmount and it should not overwrite another
|
||||||
|
// ref with the same key
|
||||||
|
if (value) {
|
||||||
|
;(doSet as SchedulerJob).id = -1
|
||||||
|
queuePostRenderEffect(doSet, parentSuspense)
|
||||||
|
} else {
|
||||||
|
doSet()
|
||||||
|
}
|
||||||
|
} else if (isRef(ref)) {
|
||||||
|
const doSet = () => {
|
||||||
|
ref.value = value
|
||||||
|
}
|
||||||
|
if (value) {
|
||||||
|
;(doSet as SchedulerJob).id = -1
|
||||||
|
queuePostRenderEffect(doSet, parentSuspense)
|
||||||
|
} else {
|
||||||
|
doSet()
|
||||||
|
}
|
||||||
|
} else if (isFunction(ref)) {
|
||||||
|
callWithErrorHandling(ref, owner, ErrorCodes.FUNCTION_REF, [value, refs])
|
||||||
|
} else if (__DEV__) {
|
||||||
|
warn('Invalid template ref type:', value, `(${typeof value})`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function invokeVNodeHook(
|
export function invokeVNodeHook(
|
||||||
hook: VNodeHook,
|
hook: VNodeHook,
|
||||||
instance: ComponentInternalInstance | null,
|
instance: ComponentInternalInstance | null,
|
||||||
|
@ -13,7 +13,7 @@ import {
|
|||||||
compatUtils
|
compatUtils
|
||||||
} from '@vue/runtime-core'
|
} from '@vue/runtime-core'
|
||||||
import { nodeOps } from './nodeOps'
|
import { nodeOps } from './nodeOps'
|
||||||
import { patchProp, forcePatchProp } from './patchProp'
|
import { patchProp } from './patchProp'
|
||||||
// Importing from the compiler, will be tree-shaken in prod
|
// Importing from the compiler, will be tree-shaken in prod
|
||||||
import { isFunction, isString, isHTMLTag, isSVGTag, extend } from '@vue/shared'
|
import { isFunction, isString, isHTMLTag, isSVGTag, extend } from '@vue/shared'
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ declare module '@vue/reactivity' {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const rendererOptions = extend({ patchProp, forcePatchProp }, nodeOps)
|
const rendererOptions = extend({ patchProp }, nodeOps)
|
||||||
|
|
||||||
// lazy create the renderer - this makes core renderer logic tree-shakable
|
// lazy create the renderer - this makes core renderer logic tree-shakable
|
||||||
// in case the user only imports reactivity utilities from Vue.
|
// in case the user only imports reactivity utilities from Vue.
|
||||||
|
@ -10,9 +10,6 @@ const nativeOnRE = /^on[a-z]/
|
|||||||
|
|
||||||
type DOMRendererOptions = RendererOptions<Node, Element>
|
type DOMRendererOptions = RendererOptions<Node, Element>
|
||||||
|
|
||||||
export const forcePatchProp: DOMRendererOptions['forcePatchProp'] = (_, key) =>
|
|
||||||
key === 'value'
|
|
||||||
|
|
||||||
export const patchProp: DOMRendererOptions['patchProp'] = (
|
export const patchProp: DOMRendererOptions['patchProp'] = (
|
||||||
el,
|
el,
|
||||||
key,
|
key,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user