util.ts 2.6 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1 2 3 4
import { hasOwn, isArray } from '@vue/shared'
import {
  ComponentOptions,
  ComponentInternalInstance,
5
  ComponentPublicInstance,
fxy060608's avatar
fxy060608 已提交
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
} from 'vue'

import { MPComponentInstance, MPComponentOptions } from './component'

export function initBehavior(options: any) {
  return Behavior(options)
}

export function initVueIds(
  vueIds: string | undefined,
  mpInstance: MPComponentInstance
) {
  if (!vueIds) {
    return
  }
  const ids = vueIds.split(',')
  const len = ids.length

  if (len === 1) {
    mpInstance._$vueId = ids[0]
  } else if (len === 2) {
    mpInstance._$vueId = ids[0]
    mpInstance._$vuePid = ids[1]
  }
}

const EXTRAS = ['externalClasses']

export function initExtraOptions(
  miniProgramComponentOptions: MPComponentOptions,
  vueOptions: ComponentOptions
) {
38
  EXTRAS.forEach((name) => {
fxy060608's avatar
fxy060608 已提交
39 40 41 42 43 44 45 46 47 48 49 50 51 52
    if (hasOwn(vueOptions, name)) {
      ;(miniProgramComponentOptions as any)[name] = vueOptions[name]
    }
  })
}

export function initWxsCallMethods(
  methods: WechatMiniprogram.Component.MethodOption,
  wxsCallMethods: WechatMiniprogram.Component.MethodOption
) {
  if (!isArray(wxsCallMethods)) {
    return
  }
  wxsCallMethods.forEach((callMethod: string) => {
53
    methods[callMethod] = function (this: MPComponentInstance, args: unknown) {
fxy060608's avatar
fxy060608 已提交
54 55 56 57 58 59 60 61 62 63 64 65 66
      return (this.$vm as any)[callMethod](args)
    }
  })
}

export function initRefs(
  instance: ComponentInternalInstance,
  mpInstance: MPComponentInstance
) {
  Object.defineProperty(instance, 'refs', {
    get() {
      const $refs: Record<string, any> = {}
      const components = mpInstance.selectAllComponents('.vue-ref')
67
      components.forEach((component) => {
fxy060608's avatar
fxy060608 已提交
68 69 70 71
        const ref = component.dataset.ref
        $refs[ref] = component.$vm || component
      })
      const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for')
72
      forComponents.forEach((component) => {
fxy060608's avatar
fxy060608 已提交
73 74 75 76 77 78 79
        const ref = component.dataset.ref
        if (!$refs[ref]) {
          $refs[ref] = []
        }
        $refs[ref].push(component.$vm || component)
      })
      return $refs
80
    },
fxy060608's avatar
fxy060608 已提交
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
  })
}

export function findVmByVueId(
  instance: ComponentPublicInstance,
  vuePid: string
): ComponentPublicInstance | undefined {
  // TODO vue3 中 没有 $children
  const $children = (instance as any).$children
  // 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
  for (let i = $children.length - 1; i >= 0; i--) {
    const childVm = $children[i]
    if (childVm.$scope._$vueId === vuePid) {
      return childVm
    }
  }
  // 反向递归查找
  let parentVm
  for (let i = $children.length - 1; i >= 0; i--) {
    parentVm = findVmByVueId($children[i], vuePid)
    if (parentVm) {
      return parentVm
    }
  }
}