Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | 84x 84x 84x 84x 84x 84x 84x 84x 120x 4x 8x 4x 116x 8x 108x 108x 108x 108x 108x 108x 108x 108x 5x 3x 3x 1x 2x 1x 108x 8x 100x 100x 100x 100x 100x 20x 20x 4x 16x 16x 7x 80x 26x 26x 14x 54x 54x 54x 100x 76x 76x 24x | import { SuspenseBoundary } from './components/Suspense' import { VNode, VNodeNormalizedRef, VNodeNormalizedRefAtom } from './vnode' import { EMPTY_OBJ, hasOwn, isArray, isFunction, isString, remove, ShapeFlags } from '@vue/shared' import { isAsyncWrapper } from './apiAsyncComponent' import { getExposeProxy } from './component' import { warn } from './warning' import { isRef } from '@vue/reactivity' import { callWithErrorHandling, ErrorCodes } from './errorHandling' import { SchedulerJob } from './scheduler' import { queuePostRenderEffect } from './renderer' /** * Function for handling a template ref */ 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 Iif (__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 { Iif (!isArray(existing)) { if (_isString) { refs[ref] = [refValue] } else { ref.value = [refValue] Iif (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 IEif (__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 IEif (__DEV__) { warn('Invalid template ref type:', ref, `(${typeof ref})`) } } } |