UNPKG

vite-uni-dev-tool

Version:

vite-uni-dev-tool, debug, uni-app, 一处编写,到处调试

238 lines (223 loc) 7.66 kB
import { isArray, isObject, isString, isSymbol } from '../../utils'; import type { ComponentInternalInstance, VNode } from 'vue'; // 类型守卫函数,检查是否为VNode类型 function isVNode(child: any): child is VNode { return child != null && typeof child === 'object' && 'type' in child; } // 类型守卫函数,检查是否为包含component属性的对象 function hasComponentProperty( child: any, ): child is VNode & { component?: ComponentInternalInstance } { return isVNode(child) && 'component' in child; } // 类型守卫函数,检查type是否具有name和__name属性 function hasNameProperty( type: any, ): type is { name?: string; __name?: string } { return isObject(type) && ('name' in type || '__name' in type); } // 类型守卫函数,检查是否为Symbol类型且具有description属性 function isSymbolWithDescription( value: any, ): value is Symbol & { description?: string } { return typeof value === 'symbol'; } /** * 简化的树节点类型 */ interface SimpleTreeNode { type: string; uid?: number; children?: SimpleTreeNode[]; content?: string; } /** * 简化树结构,只保留在ComponentInternalInstance中必要的属性 * @param vNode - Vue组件内部实例 * @returns 简化的树结构 */ export function simpleTree(vNode?: any): SimpleTreeNode | null { if (!vNode) { return null; } // 确保只使用必需的属性 const simplifiedInstance: InstanceTree.SimplifiedComponentInternalInstance = { type: vNode.type, subTree: vNode.subTree, uid: vNode.uid, ...(vNode.component && { component: vNode.component }), ...(vNode.children && { children: vNode.children }), }; const children: SimpleTreeNode[] = []; // 获取子节点 if (simplifiedInstance.subTree) { // 处理 subTree 的 children if ('data-dev-tool' in (simplifiedInstance.subTree.props ?? {})) { // 排除dev tool 节点 } else if ( simplifiedInstance.subTree.children && isArray(simplifiedInstance.subTree.children) ) { for (const child of simplifiedInstance.subTree.children) { if (hasComponentProperty(child) && child?.component) { // 子组件实例 const childTree = simpleTree(child.component); if (childTree) { children.push(childTree); } } else if (isVNode(child) && child?.type) { if (isObject(child.type)) { children.push({ type: hasNameProperty(child.type) ? child.type.name || child.type.__name || 'Anonymous' : 'Anonymous', children: child.children ? getSimpleChildrenFromVNode(child) : [], }); } else if (isString(child.type)) { children.push({ type: child.type, children: child.children ? getSimpleChildrenFromVNode(child) : [], }); } else { if ( child.type && isSymbolWithDescription(child.type) && (child.type.description === 'v-fgt' || child.type.description === 'v-txt' || child.type.description === 'v-cmt') ) { // 跳过虚拟节点 // 跳过当前层直接处理下一层 const fragmentChildren = getSimpleChildrenFromVNode(child); children.push(...fragmentChildren); } } } else if (isString(child)) { // 处理字符串类型的子节点 children.push({ type: 'text', content: child, }); } } } // 如果 subTree 是组件实例 else if (simplifiedInstance.subTree.component) { const childTree = simpleTree(simplifiedInstance.subTree.component); if (childTree) { children.push(childTree); } } } // 构建当前节点 let nodeInfo: SimpleTreeNode; if (isObject(simplifiedInstance.type)) { nodeInfo = { type: hasNameProperty(simplifiedInstance.type) ? simplifiedInstance.type.name || simplifiedInstance.type.__name || 'Component' : 'Component', uid: simplifiedInstance.uid, // 添加唯一标识 children, }; } else if (isString(simplifiedInstance.type)) { nodeInfo = { type: simplifiedInstance.type, uid: simplifiedInstance.uid, // 添加唯一标识 children, }; } else { nodeInfo = { type: 'template', uid: simplifiedInstance.uid, children, }; } return nodeInfo; } /** * 从 VNode 获取简化的子节点 */ function getSimpleChildrenFromVNode(vnode: any): SimpleTreeNode[] { const children: SimpleTreeNode[] = []; if (vnode.children) { if (isArray(vnode.children)) { for (const child of vnode.children) { if (hasComponentProperty(child) && child?.component) { // 优先处理组件实例 const childTree = simpleTree(child.component); if (childTree) { children.push(childTree); } } else if (isVNode(child) && child?.type) { if (isObject(child.type)) { children.push({ type: hasNameProperty(child.type) ? child.type?.name || child.type?.__name || 'Anonymous' : 'Anonymous', children: child.children ? getSimpleChildrenFromVNode(child) : [], }); } else if (isString(child.type)) { children.push({ type: child.type, children: child.children ? getSimpleChildrenFromVNode(child) : [], }); } else { // 处理文本节点或其他类型节点 if ( child.type && isSymbolWithDescription(child.type) && (child.type.description === 'v-fgt' || child.type.description === 'v-txt' || child.type.description === 'v-cmt') ) { // 跳过当前层直接处理下一层 const fragmentChildren = getSimpleChildrenFromVNode(child); children.push(...fragmentChildren); } else { // 处理其他类型的节点 children.push({ type: typeof child.type !== 'object' ? isSymbolWithDescription(child.type) ? child.type.description || 'symbol-node' : String(child.type) : 'unknown-node', children: child.children ? getSimpleChildrenFromVNode(child) : [], }); } } } else if (isString(child)) { // 处理字符串类型的子节点 children.push({ type: 'text', content: child, }); } } } else if (isString(vnode.children)) { // 处理文本节点 // 过滤空的 v-txt 节点 if ( isSymbolWithDescription(vnode.type) && vnode.type?.description === 'v-txt' ) { // 文本节点 children.push({ type: '', content: vnode.children, }); } else { // 注释节点 children.push({ type: vnode.type?.description || '', content: vnode.children, }); } } } return children; }