巧用Vue3 composition api的计算属性实现扁平化tree连线

本示例节选自vue3最新开源组件实战教程大纲(持续更新中)的tree组件开发部分。将进一步把基于Vue3 composition api的computed计算属性特性应用到组件开发实战中,继续以最佳实践的方式呈现给大家。

下面我们要实现的是扁平化的dom结构所呈现的树形组件增加参照线的功能。

这种结构不同于传统嵌套dom实现的树作参照线那么简单,需要动态计算线的长度,正好我们可以充分应用vue3给我们提供的composition api的计算属性computed。一切都变得非常简单,Life is so easy!

节点属性

新增节点属性

ts 复制代码
export interface ITreeNode {
  ...
  visibleLength?: ComputedRef<number> // 展开可见的节点长度
  lineLength?: ComputedRef<number> // 节点参照线的长度
}

计算属性

核心的初始化方法

ts 复制代码
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)
  })
}

在拍平函数中调用父节点初始化函数:

组件完善

模板完善

试着打印父节点的参照线长度

看下效果:

展开、折叠,参照线并不会动态变化。修复下:

再看效果,删除节点测试还有问题:

修复下:

完美!

相关推荐
苏卫苏卫苏卫13 小时前
【码源】智能无人仓库管理系统(详细码源下~基于React+TypeScript+Vite):
前端·react.js·typescript·vite·项目设计·智能无人仓库管理系统·码源
Sheldon一蓑烟雨任平生1 天前
Vue3 重构待办事项(主要练习组件化)
vue.js·重构·vue3·组件化练习
代码哈士奇1 天前
使用vite+vue3+ElementPlus+pinia搭建中后台应用-前端
前端·vue3·管理系统·vite7
Sheldon一蓑烟雨任平生2 天前
Vue3 透传 Attributes
vue.js·vue3·透传attributes·禁用attributes继承·深层组件继承
Sheldon一蓑烟雨任平生2 天前
Vue3 生命周期
vue3·生命周期·1024程序员节·setup·vue3 生命周期·vue2 生命周期
一只小阿乐3 天前
vue3 中实现父子组件v-model双向绑定 总结
前端·javascript·vue.js·vue3·组件·v-model语法糖
IT教程资源C4 天前
(N_157)基于springboot,vue服装商城系统
mysql·vue3·前后端分离·springboot服装商城
Sheldon一蓑烟雨任平生4 天前
Vue3 组件 v-model
vue.js·vue3·v-model·definemodel·v-model修饰符·自定义双向绑定组件·多个v-model绑定
嗷呜~4 天前
error 找不到模块“../views/Login.vue”或其相应的类型声明
typescript·vue3
加蓓努力我先飞4 天前
Vue3小兔鲜-(二)
前端·javascript·css·vue3