本示例节选自vue3最新开源组件实战教程大纲(持续更新中)的tree组件开发部分。将进一步把基于Vue3 composition api的computed
计算属性特性应用到组件开发实战中,继续以最佳实践的方式呈现给大家。
下面我们要实现的是扁平化的dom结构所呈现的树形组件增加参照线的功能。
这种结构不同于传统嵌套dom
实现的树作参照线那么简单,需要动态计算线的长度,正好我们可以充分应用vue3给我们提供的composition api的计算属性computed
。一切都变得非常简单,Life is so easy!
节点属性
新增节点属性
export interface ITreeNode {
...
visibleLength?: ComputedRef<number> // 展开可见的节点长度
lineLength?: ComputedRef<number> // 节点参照线的长度
}
计算属性
核心的初始化方法
function initParentNode(node: ITreeNode, optionProps: OptionProps) {
const nodeRef = ref<ITreeNode>(node)
const childrenName = optionProps.childrenName as 'children'
// 可见节点长度计算属性
node.visibleLength = computed(() => {
// 如果不是展开的返回0
if (!nodeRef.value.expanded) return 0
// 遍历原始树结构的子节点列表,判断如果是父节点,则继续递归调用其visibleLength计算属性
// 通过reduce实现累加
return nodeRef.value[childrenName]!.reduce((count, cur) => count + (cur[childrenName] ? (cur.expanded ? 1 + cur.visibleLength! : 1) : 1), 0)
})
// 计算父节点的参照线长度
node.lineLength = computed(() => {
// 如果是折叠的直接返回0
if (!nodeRef.value.expanded) return 0
// 否则用可见长度 - 子一代最后一个节点的可见长度
const children = nodeRef.value[childrenName]
const lastChild = children![children!.length - 1]
return nodeRef.value.visibleLength! - (lastChild.visibleLength || 0)
})
}
在拍平函数中调用父节点初始化函数:
组件完善
模板完善
试着打印父节点的参照线长度
看下效果:
展开、折叠,参照线并不会动态变化。修复下:
再看效果,删除节点测试还有问题:
修复下:
完美!