Vue实现封装树状图的示例代码
封装准备 完整代码可直接置底查看
组件的封装来源于数据
我们把树状图(下文统称为“图”)的每一个节点作为一个看作一个对象,它将需要的节点属性如下:
| 属性名称 | 作用 |
|---|---|
| id | 唯一标识 |
| title | 节点名称 |
| children | 子集 |
| expend | 展开控制变量 |
//数据准备
let treeData = [
{
id: 'treeRoot',
title: '目录根节点',
expend: false,
children: [
{
id: 'subNode',
title: '目录子节点',
}
],
},
];
开始封装
我们确认了图的数据是一个可以无限递归的层级数据,所以我们首先需要封装一个方法来遍历数据。
//树状图数据遍历方法
function TreeNode(arr) {
return arr.reduce((pre, cur) => {
if (cur.children && Array.isArray(cur.children)) {
cur.children = TreeNode(cur.children);
}
pre.push(cur);
return pre;
}, []);
}
其次是组件内部结构,我们需要用到递归组件,所谓的递归组件就是在vue单文件内部给予name属性,我们就可以在该文件内直接调用组件。
<template>
<div class="tree">
<div class="tree-item" v-for="item in treeData" :key="item.id">
<div>{{ item.title }}</div>
<Tree :treeData="item.children || []" />
</div>
</div>
</template>
<script>
export default {
name: 'Tree',
props: {
treeData: {
default: [
{
id: 'treeRoot',
title: '目录根节点',
expend: false,
children: [
{
id: 'subNode',
title: '目录子节点',
},
],
},
],
},
},
};
</script>
视图效果

接下来我们为每一级节点添加缩进,我们定义一个初始值pad,当用户调用时未传pad,此时采用默认值,pad为0,接下来每一级逐级+1传递,即可实现节点缩进效果。
<Tree :treeData="item.children" :pad="pad+1">
pad: {
type: Number,
default: 0,
},
当数据多出之后,我们需要为图添加展开/收起功能,用expend控制Tree 展示隐藏即可
<Tree :treeData='item.children' v-if="item.expend" :pad="pad+1">
我们可以添加一些图标或者标签来当作操作按钮,这里不予多做解释。至于不定高度的展开收起动画,我采用grid的template-rows:1fr/0fr;来实现动画的高度变化。
.tree-sub {
display: grid;
transition: all 0.3s;
}
.tree-item-expend {
grid-template-rows: 1fr;
}
.tree-item-hidden {
grid-template-rows: 0fr;
}
此后,树状图的已具有初步效果,我们还需要再继续进行一些细微之处的修改。各位同学可以通过CV查看具体效果或继续进行封装修改。
完整代码
<template>
<div class="tree">
<div class="tree-item" v-for="item in treeData" :key="item.id">
<div class="tree-item-row" :style="`padding-left:${pad}rem`">
<div class="tree-item-row-opr" @click.stop="item.expend = !item.expend" v-if="item.children && Array.isArray(item.children)">
{{ item.expend ? '-' : '+' }}
</div>
<div class="tree-item-row-opr-none" v-else></div>
<div class="tree-item-row-text">{{ item.title }}</div>
</div>
<div
class="tree-sub"
:class="{
'tree-item-expend': item.expend,
'tree-item-hidden': !item.expend,
}"
>
<Tree :treeData="item.children || []" :pad="pad + 1" />
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Tree',
props: {
treeData: {
Type: Array,
default: () => [
{
id: 'treeRoot',
title: '目录根节点',
expend: false,
children: [
{
id: 'subNode1',
title: '目录子节点1',
expend: false,
children: [
{
id: 'subNode11',
title: '目录子节点1-1',
},
{
id: 'subNode12',
title: '目录子节点1-2',
},
{
id: 'subNode13',
title: '目录子节点1-3',
},
{
id: 'subNode14',
title: '目录子节点1-4',
},
],
},
{
id: 'subNode2',
title: '目录子节点2',
},
{
id: 'subNode3',
title: '目录子节点3',
},
{
id: 'subNode4',
title: '目录子节点4',
},
{
id: 'subNode5',
title: '目录子节点5',
},
{
id: 'subNode6',
title: '目录子节点6',
},
],
},
],
},
pad: {
type: Number,
default: 0,
},
},
};
</script>
<style lang="less">
.tree {
box-sizing: border-box;
overflow: hidden;
&-item {
display: flex;
flex-direction: column;
gap: 4px;
&-row {
display: flex;
gap: 4px;
&-opr {
cursor: pointer;
width: 16px;
font-size: 16px;
height: 20px;
line-height: 20px;
text-align: center;
}
&-opr-none {
cursor: default;
}
}
.tree-sub {
display: grid;
transition: all 0.3s;
}
.tree-item-expend {
grid-template-rows: 1fr;
}
.tree-item-hidden {
grid-template-rows: 0fr;
}
}
}
</style>组件封装为系列作品,树状图组件远远不止于此,开发还有特定需求,如关键字检索,目录检索,多选,单选,懒加载,标题超长缩略提示等。
到此这篇关于Vue实现封装树状图的示例代码的文章就介绍到这了,更多相关Vue封装树状图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
vue封装自定义指令之动态显示title操作(溢出显示,不溢出不显示)
这篇文章主要介绍了vue封装自定义指令之动态显示title操作(溢出显示,不溢出不显示),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-11-11
vue中的任务队列和异步更新策略(任务队列,微任务,宏任务)
这篇文章主要介绍了vue中的任务队列和异步更新策略(任务队列,微任务,宏任务),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-08-08
vue3.0 CLI - 2.3 - 组件 home.vue 中学习指令和绑定
这篇文章主要介绍了vue3.0 CLI - 2.3 - 组件 home.vue 中学习指令和绑定的相关知识,本文通过实例代码相结合的形式给大家介绍的非常详细 ,需要的朋友可以参考下2018-09-09


最新评论