vue动态生成多级树结构
vue 根据有多个子节点的数据动态生成树结构。
·
前言
技术栈:vue + Quasar Framework
在开发的时候想要在树结构里面每个节点数据都能实现某种功能(像表格一样有操作的功能),而且不能确定数据有多少层级。基于后续会想要添加节点间互相拖拽的功能,这里使用UI框架提供的树组件不理想,故用vue写一个。
vue 根据有多个子节点的数据动态生成树结构。
一、思路
写一个树结构的封装组件,因为不知道数据的层级,所以在封装的组件里面调用自身,实现一个自身组件的嵌套,我们只需要在嵌套组件的时候做好有子节点才嵌套,无则不嵌套的判断。
二、封装组件的代码
1.组件里的template
class=“row bg_row” 这种样式的写法是Quasar Framework框架里自带的,需要去看文档,如果没有用这个框架的,样式自己写,这里不用理会。
<template>
<div id="children_tree">
<!-- 将数据正常地循环展示 - 组件传入数据数组 parentTreeData -->
<div v-for="item in parentTreeData" :key="item.category_id">
<div class="row bg_row">
<!-- 数据的左边部分 - showHidden点击方法是控制节点是否展开 -->
<div class="col" @click="showHidden(item)">
<i
v-if="
item.son &&
item.son instanceof Array &&
item.son.length > 0 &&
!findTrue(item.category_id)
"
class="material-icons draicon"
>arrow_right</i
>
<i
v-else-if="
item.son &&
item.son instanceof Array &&
item.son.length > 0 &&
findTrue(item.category_id)
"
class="material-icons draicon"
>arrow_drop_down</i
>
<i
v-else
class="material-icons draicon"
style="padding-left: 38px"
></i>
{{ item.name }}
</div>
<!-- 数据的右边放功能按钮的部分 - 接收传入的功能数组 btnOperates -->
<div :class="`col-${5}`" style="text-align: right">
<q-btn
class="on-left"
v-for="(btn, index) in btnOperates"
:key="`btn_fun_${index}`"
:label="btn.label || '按钮'"
:color="btn.color || 'primary'"
:outline="btn.outline || false"
:size="btn.size || 'md'"
@click="btn.fun(item)"
unelevated
/>
</div>
</div>
<!-- 调用自己 -->
<children
v-if="item.son && findTrue(item.category_id)"
:key="item.category_id + 10000"
:parent-tree-data="item.son"
:tree-data="treeData"
:btn-operates="btnOperates"
style="margin-left: 15px"
></children>
</div>
</div>
</template>
2.组件里的script
<script>
export default {
name: 'children',
props: {
// 传入数据
parentTreeData: {
type: Array,
default: () => {
return []
}
},
// 功能按钮
btnOperates: {
type: Array,
default: () => {
return []
}
}
},
data() {
return {
// 用于存储是否展开显示的层级
showArr: []
}
},
methods: {
// 展开或者隐藏下级目录
showHidden(item) {
if (this.showArr.includes(item.category_id)) {
// 存在
this.remove(this.showArr, item.category_id)
} else {
// 不存在
this.showArr.push(item.category_id)
}
},
remove(arr, item) {
for (let index = 0; index < arr.length; index++) {
const element = arr[index]
if (element == item) {
arr.splice(index, 1)
}
}
},
// 是否展示
findTrue(id) {
return this.showArr.includes(id)
}
}
}
</script>
3.style
.bg_row {
width: 100%;
height: 50px;
line-height: 50px;
background-color: #eeeeee;
color: #000000;
margin: 2px 0 2px 0;
}
.draicon {
font-size: 32px;
color: #7e7e7e;
padding-left: 6px;
}
三、使用步骤
1.调用组件
<cate-tree
:parentTreeData="list"
:btnOperates="operates"
/>
2.传入数据
import cateTree from './components/cate-tree' // 组件名称自定义哈
export default {
components: { cateTree },
data() {
return {
list: [
{
category_id: 100,
name: '父级一',
parent_id: 0,
son: [
{
category_id: 103,
name: '子级一',
parent_id: 100,
son: [
{
category_id: 106,
name: '孙级一',
parent_id: 103,
son: [
{
category_id: 107,
name: '曾孙级一',
parent_id: 106
}
]
}
]
}
]
},
{
category_id: 101,
name: '父级二',
parent_id: 0,
son: [
{
category_id: 104,
name: '子级一',
parent_id: 101
}
]
},
{
category_id: 102,
name: '父级三',
parent_id: 0,
son: []
}
],
operates: [
{
label: '當前分類商品',
color: 'primary',
size: 'md',
outline: true,
fun: (row) => {
// 放功能方法
}
},
{
label: '修改',
color: 'primary',
size: 'md',
outline: false,
fun: (row) => {
// 放功能方法
}
},
{
label: '刪除',
color: 'red',
size: 'md',
outline: false,
fun: (row) => {
// 放功能方法
}
}
]
}
}
}
3.实现的效果
如下图(部分展开)
(全部展开)
总结
传入的数据改成是接口获取,因为是组件调用自身,所以不管数据有多少层级,都能渲染。
更多推荐
已为社区贡献1条内容
所有评论(0)