|
|
@@ -9,17 +9,15 @@ import {
|
|
|
createVNode,
|
|
|
isSameVNodeType,
|
|
|
Static,
|
|
|
- VNodeNormalizedRef,
|
|
|
VNodeHook,
|
|
|
- VNodeNormalizedRefAtom,
|
|
|
- VNodeProps
|
|
|
+ VNodeProps,
|
|
|
+ invokeVNodeHook
|
|
|
} from './vnode'
|
|
|
import {
|
|
|
ComponentInternalInstance,
|
|
|
ComponentOptions,
|
|
|
createComponentInstance,
|
|
|
Data,
|
|
|
- getExposeProxy,
|
|
|
setupComponent
|
|
|
} from './component'
|
|
|
import {
|
|
|
@@ -29,19 +27,15 @@ import {
|
|
|
updateHOCHostEl
|
|
|
} from './componentRenderUtils'
|
|
|
import {
|
|
|
- isString,
|
|
|
EMPTY_OBJ,
|
|
|
EMPTY_ARR,
|
|
|
isReservedProp,
|
|
|
- isFunction,
|
|
|
PatchFlags,
|
|
|
ShapeFlags,
|
|
|
NOOP,
|
|
|
- hasOwn,
|
|
|
invokeArrayFns,
|
|
|
isArray,
|
|
|
- getGlobalThis,
|
|
|
- remove
|
|
|
+ getGlobalThis
|
|
|
} from '@vue/shared'
|
|
|
import {
|
|
|
queueJob,
|
|
|
@@ -51,16 +45,12 @@ import {
|
|
|
flushPreFlushCbs,
|
|
|
SchedulerJob
|
|
|
} from './scheduler'
|
|
|
-import {
|
|
|
- isRef,
|
|
|
- pauseTracking,
|
|
|
- resetTracking,
|
|
|
- ReactiveEffect
|
|
|
-} from '@vue/reactivity'
|
|
|
+import { pauseTracking, resetTracking, ReactiveEffect } from '@vue/reactivity'
|
|
|
import { updateProps } from './componentProps'
|
|
|
import { updateSlots } from './componentSlots'
|
|
|
import { pushWarningContext, popWarningContext, warn } from './warning'
|
|
|
import { createAppAPI, CreateAppFunction } from './apiCreateApp'
|
|
|
+import { setRef } from './rendererTemplateRef'
|
|
|
import {
|
|
|
SuspenseBoundary,
|
|
|
queueEffectWithSuspense,
|
|
|
@@ -69,11 +59,6 @@ import {
|
|
|
import { TeleportImpl, TeleportVNode } from './components/Teleport'
|
|
|
import { isKeepAlive, KeepAliveContext } from './components/KeepAlive'
|
|
|
import { registerHMR, unregisterHMR, isHmrUpdating } from './hmr'
|
|
|
-import {
|
|
|
- ErrorCodes,
|
|
|
- callWithErrorHandling,
|
|
|
- callWithAsyncErrorHandling
|
|
|
-} from './errorHandling'
|
|
|
import { createHydrationFunctions, RootHydrateFunction } from './hydration'
|
|
|
import { invokeDirectiveHook } from './directives'
|
|
|
import { startMeasure, endMeasure } from './profiling'
|
|
|
@@ -2351,124 +2336,6 @@ 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 (isFunction(ref)) {
|
|
|
- callWithErrorHandling(ref, owner, ErrorCodes.FUNCTION_REF, [value, refs])
|
|
|
- } else {
|
|
|
- const _isString = isString(ref)
|
|
|
- const _isRef = isRef(ref)
|
|
|
- if (_isString || _isRef) {
|
|
|
- const doSet = () => {
|
|
|
- if (rawRef.f) {
|
|
|
- const existing = _isString ? refs[ref] : ref.value
|
|
|
- if (isUnmount) {
|
|
|
- isArray(existing) && remove(existing, refValue)
|
|
|
- } else {
|
|
|
- if (!isArray(existing)) {
|
|
|
- if (_isString) {
|
|
|
- refs[ref] = [refValue]
|
|
|
- } else {
|
|
|
- ref.value = [refValue]
|
|
|
- if (rawRef.k) refs[rawRef.k] = ref.value
|
|
|
- }
|
|
|
- } else if (!existing.includes(refValue)) {
|
|
|
- existing.push(refValue)
|
|
|
- }
|
|
|
- }
|
|
|
- } else if (_isString) {
|
|
|
- refs[ref] = value
|
|
|
- if (hasOwn(setupState, ref)) {
|
|
|
- setupState[ref] = value
|
|
|
- }
|
|
|
- } else if (isRef(ref)) {
|
|
|
- ref.value = value
|
|
|
- if (rawRef.k) refs[rawRef.k] = value
|
|
|
- } else if (__DEV__) {
|
|
|
- warn('Invalid template ref type:', ref, `(${typeof ref})`)
|
|
|
- }
|
|
|
- }
|
|
|
- if (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
|
|
|
- ;(doSet as SchedulerJob).id = -1
|
|
|
- queuePostRenderEffect(doSet, parentSuspense)
|
|
|
- } else {
|
|
|
- doSet()
|
|
|
- }
|
|
|
- } else if (__DEV__) {
|
|
|
- warn('Invalid template ref type:', ref, `(${typeof ref})`)
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-export function invokeVNodeHook(
|
|
|
- hook: VNodeHook,
|
|
|
- instance: ComponentInternalInstance | null,
|
|
|
- vnode: VNode,
|
|
|
- prevVNode: VNode | null = null
|
|
|
-) {
|
|
|
- callWithAsyncErrorHandling(hook, instance, ErrorCodes.VNODE_HOOK, [
|
|
|
- vnode,
|
|
|
- prevVNode
|
|
|
- ])
|
|
|
-}
|
|
|
-
|
|
|
function toggleRecurse(
|
|
|
{ effect, update }: ComponentInternalInstance,
|
|
|
allowed: boolean
|