UNPKG

wot-design-uni

Version:

一个基于Vue3+TS开发的uni-app组件库,提供70+高质量组件,支持暗黑模式、国际化和自定义主题。

114 lines (96 loc) 3.04 kB
import { provide, reactive, getCurrentInstance, type VNode, type InjectionKey, type VNodeNormalizedChildren, type ComponentPublicInstance, type ComponentInternalInstance } from 'vue' // 小程序端不支持从vue导出的isVNode方法,参考uni-mp-vue的实现 function isVNode(value: any): value is VNode { return value ? value.__v_isVNode === true : false } export function flattenVNodes(children: VNodeNormalizedChildren) { const result: VNode[] = [] const traverse = (children: VNodeNormalizedChildren) => { if (Array.isArray(children)) { children.forEach((child) => { if (isVNode(child)) { result.push(child) if (child.component?.subTree) { result.push(child.component.subTree) traverse(child.component.subTree.children) } if (child.children) { traverse(child.children) } } }) } } traverse(children) return result } const findVNodeIndex = (vnodes: VNode[], vnode: VNode) => { const index = vnodes.indexOf(vnode) if (index === -1) { return vnodes.findIndex((item) => vnode.key !== undefined && vnode.key !== null && item.type === vnode.type && item.key === vnode.key) } return index } // sort children instances by vnodes order export function sortChildren( parent: ComponentInternalInstance, publicChildren: ComponentPublicInstance[], internalChildren: ComponentInternalInstance[] ) { const vnodes = parent && parent.subTree && parent.subTree.children ? flattenVNodes(parent.subTree.children) : [] internalChildren.sort((a, b) => findVNodeIndex(vnodes, a.vnode) - findVNodeIndex(vnodes, b.vnode)) const orderedPublicChildren = internalChildren.map((item) => item.proxy!) publicChildren.sort((a, b) => { const indexA = orderedPublicChildren.indexOf(a) const indexB = orderedPublicChildren.indexOf(b) return indexA - indexB }) } export function useChildren< // eslint-disable-next-line Child extends ComponentPublicInstance = ComponentPublicInstance<{}, any>, ProvideValue = never >(key: InjectionKey<ProvideValue>) { const publicChildren: Child[] = reactive([]) const internalChildren: ComponentInternalInstance[] = reactive([]) const parent = getCurrentInstance()! const linkChildren = (value?: ProvideValue) => { const link = (child: ComponentInternalInstance) => { if (child.proxy) { internalChildren.push(child) publicChildren.push(child.proxy as Child) sortChildren(parent, publicChildren, internalChildren) } } const unlink = (child: ComponentInternalInstance) => { const index = internalChildren.indexOf(child) publicChildren.splice(index, 1) internalChildren.splice(index, 1) } provide( key, Object.assign( { link, unlink, children: publicChildren, internalChildren }, value ) ) } return { children: publicChildren, linkChildren } }