递归组件
一个简单的递归组件如下例所示:
tree.vue
<template>
<ul class="child-node">
<li class="vue-tree-item" v-for="(item, index) in treeDataList" :key="index">
<div class="tree-node"
:style="pLeft" @click="toggleChildren(item)">
{{item.name}}
</div>
<exportTree
v-if="item.children"
:tree-data-list="item.children"
:tree-index="treeIndex + 1"
@toggleChildren="toggleChildren">
</exportTree>
</li>
</ul>
</template>
<script>
export default {
name: 'exportTree',
props: {
treeDataList: {
type: Array,
default: []
},
treeIndex: {
type: Number,
default: 0
}
},
data () {
return {
pLeft: `padding-left:${15 * (this.treeIndex + 1)}px;`
}
},
methods: {
toggleChildren (item) {
this.$emit('toggleChildren', item)
}
}
}
</script>
index.vue
<template>
<div class="module-content-wrapper" style="width: 200px;border: 1px solid #ccc;">
<exportTree
:tree-data-list="treeDataList"
@toggleChildren="toggleChildren">
</exportTree>
</div>
</template>
<script>
import exportTree from 'components/exportTree/exportTree'
export default {
components: {
exportTree
},
data () {
return {
treeDataList: [
{
"id": 1,
"name": "总公司",
"order": 1,
"parent": null,
"children": [
{
"id": 2,
"name": "研发部门1",
"parent": 1,
"order": 1,
"has_children": false
},
{
"id": 3,
"name": "jx",
"parent": 1,
"order": 2,
"has_children": false
}
]
}
]
}
},
methods: {
toggleChildren (item) {
console.log(item)
}
}
}
</script>
总结:
- 组件内调用组件,本来就是一种递归的思想。绑定的treeDataList有多少层级,那就会递归多少层,因为每一层都有v-for都会循环子节点。
注意:组件内调用组件,需要有一个条件来终止递归
- 递归组件必须含有name这个属性(name指的是组件的名字),因为没有name这个属性会造成空间自身不能调用自身
遇到的问题:
tree组件有菜单功能:上移、下移。 因为层级太深,会导致真正的index值丢失
解决:
在初始化递归处理数据时,添加对应的引用父级(即直接父级)
this.treeDataList.forEach(item => {
this.addParent(item, this.treeDataList)
})
function addParent (tree, directParent) {
/**
* tree : 当前的节点 {}
* parent: 当前节点的父级[]
*/
tree.directParent = directParent
if (tree.children == null) {
return
}
tree.children.forEach(item => {
this.addParent(item, tree)
})
}