vue.ts 1.6 KB
Newer Older
1 2 3 4 5
import type {
  ComponentInternalInstance,
  ComponentPublicInstance,
  VNode,
} from '@vue/runtime-core'
fxy060608's avatar
fxy060608 已提交
6 7 8
import { hyphenate } from '@vue/shared'

import { isBuiltInComponent } from './tags'
fxy060608's avatar
fxy060608 已提交
9
import { SLOT_DEFAULT_NAME } from './constants'
fxy060608's avatar
fxy060608 已提交
10

11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
export function isComponentInternalInstance(
  vm: unknown
): vm is ComponentInternalInstance {
  return !!(vm as ComponentInternalInstance).appContext
}

export function resolveComponentInstance(
  instance?: ComponentInternalInstance | ComponentPublicInstance
) {
  return (
    instance &&
    (isComponentInternalInstance(instance) ? instance.proxy! : instance)
  )
}

fxy060608's avatar
fxy060608 已提交
26 27 28 29 30 31 32 33 34 35 36 37
export function resolveOwnerVm(vm: ComponentInternalInstance) {
  if (!vm) {
    return
  }
  let componentName = vm.type.name
  while (componentName && isBuiltInComponent(hyphenate(componentName))) {
    // ownerInstance 内置组件需要使用父 vm
    vm = vm.parent!
    componentName = vm.type.name
  }
  return vm.proxy!
}
fxy060608's avatar
fxy060608 已提交
38 39 40 41 42 43 44 45 46 47 48 49 50 51

function isElement(el: Element) {
  // Element
  return el.nodeType === 1
}

export function resolveOwnerEl(instance: ComponentInternalInstance) {
  const { vnode } = instance
  if (isElement(vnode.el as Element)) {
    return vnode.el
  }
  const { subTree } = instance
  // ShapeFlags.ARRAY_CHILDREN = 1<<4
  if (subTree.shapeFlag & 16) {
fxy060608's avatar
fxy060608 已提交
52 53
    const elemVNode = (subTree.children as VNode[]).find(
      (vnode) => vnode.el && isElement(vnode.el as Element)
fxy060608's avatar
fxy060608 已提交
54 55 56 57 58 59 60
    )
    if (elemVNode) {
      return elemVNode.el
    }
  }
  return vnode.el
}
fxy060608's avatar
fxy060608 已提交
61 62 63 64

export function dynamicSlotName(name: string) {
  return name === 'default' ? SLOT_DEFAULT_NAME : name
}