更新:登录功能
This commit is contained in:
113
uni_modules/wot-design-uni/components/composables/useChildren.ts
Normal file
113
uni_modules/wot-design-uni/components/composables/useChildren.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user