- 作者:老汪软件技巧
- 发表时间:2024-12-29 07:05
- 浏览量:
从0到1,手把手带你用 vue 实现最简单的树状控件
很多初学者可能觉得实现一个树结构的控件很难, 觉得树状结构很复杂,不好处理
实际上树状控件只需要你对递归、数组有基本的掌握,就可以很轻松的实现出来了
1. 数据结构
对于数据结构,其实就是简单的树状结构,每一个节点如果有子节点,那么就放入到该节点的 children 列表中
const list = reactive([
{
id: 1,
name: 1,
// 子节点
children: [
{
id: 2,
name: 2,
// 子节点
children: [
{
id: 3,
name: 3
}
]
},
{
id: 4,
name: 4
}
]
},
{
id: 5,
name: 5
}
]);
需要注意的是,后端有可能只会返回给我们平铺的数据结构,类似于
[
{id: 1, name: 1},
{id: 2, name: 2, parentId: 1},
{id: 4, name: 4, parentId: 1},
{id: 3, name: 3, parentId: 2},
{id: 5, name: 5}
]
这种就需要我们对数据做处理,将数据转换为树状的结构,方便我们后续渲染
function listToTree (list) {
let result = []
for (let item of list) {
// 如果父节点为空,则直接放入数组中
if (item.parentId == null) {
result.push(item)
} else {
// 否则找到父节点,放到父节点的 children 列表中
let index = list.findIndex(child => child.id == item.parentId)
if (list[index].children == null){
list[index].children = []
}
list[index].children.push(item)
}
}
return result
}
2. 组件编写
数据结构准备好之后,我们直接就可以开始组件编写了
首先我们需要准备一个父容器 TreeBox,用来处理整体树的逻辑、以及渲染整个第一层级的结构
<template>
<div>
<TreeItem :key="item.id" v-for="item in data" :value="item">TreeItem>
div>
template>
这里 props 传入的 data 就是我们上面准备好的数据结构
模板中通过 for 循环来展示我们树结构中所有顶层的节点
然后我们就可以开始定义 TreeItem 子节点了
<template>
<div>
<div class="list-box">
<div class="name">
<div >{{ value.name }}div>
div>
// 渲染子节点
<div class="child-box" v-if="value.children">
<tree-item v-for="item in value.children" :key="item.id" :value="item">tree-item>
div>
div>
div>
template>
子节点也是非常简单
value 就是我们刚刚传入的顶层节点本身,然后我们在 child-box 判断节点是否有子元素列表,如果有就循环子元素列表,递归我们的 tree-item 节点
这样就可以一层一层递归渲染我们所有的子节点了
…
其实最主要是就 递归 , 也就是子节点自己来判断自己是否还需要渲染子节点
子子节点中也有判断自己是否还需要渲染子节点
这样依次判断之后,所有节点就都渲染出来了
如果我们不使用 递归子节点 而是使用 单个节点 循环来做的话,当然也可以,但是会非常的麻烦。
递归子节点 大部分情况是最省事的做法