这是原网址:https://www.moyublog.com/codes/237.html
在tree.vue中
<template>
<ul class="l_tree" v-if="model.length">
<li class="l_tree_branch" v-for="(item,index) in model" :key="index">
<div class="l_tree_click">
<span @click="toggle(item,index)">
<button
type="button"
class="l_tree_children_btn"
v-if="item.child.length>0"
>
<span v-if="item.show">
<!-- <i class="i_icon">-</i> -->
<i class="el-icon-folder-remove"></i>
</span>
<span v-else>
<!-- <i class="i_icon">+</i> -->
<i class="el-icon-folder-add"></i>
</span>
</button>
<i v-else class="el-icon-document"></i>
<span class="l_folder" :style="{color:$store.state.dataId==item.id?'red':'',}">{{ item.name }}</span>
</span>
</div>
<tree
v-show="item.show"
v-if="item.child"
:model="item.child"
></tree>
</li>
</ul>
</template>
<script>
import tree from "./tree.vue";
export default {
name: "tree",
components: {
tree
},
watch: {
// value:"选项1"
},
props: ['model'],
data() {
return {
};
},
mounted() {
// this.value="选项6"
// console.log(this.model)
},
methods: {
search(obj, name, namePath = []) {
for (let i = 0, len = obj.length; i < len; i++) {
let item = obj[i]
if (item.name === name) {
namePath.push(name)
item.expand = true
return {
has: true,
namePath
}
} else if (item.child && item.child.length) {
namePath.push(item.topId)
let result = this.search(item.child, name, namePath)
if (result.has) return {has: true, namePath}
namePath.pop()
}
}
return {
has: false
}
},
toggle: function(item,index) {
// console.log(item,this.model,this.$store.state.testdata);
// this.model.filter(item => item.topId !=item.item).show = false
let topId;
if(item.child.length == 0) {
topId = this.search(this.$store.state.testdata,item.name).namePath[0] // this.$store.state.testdata存放的是完整的数据
this.$store.commit('stateFun',{ name: 'dataId', val: item.id }) this.$store.commit('stateFun',{ name: 'topId', val: topId }) console.log(this.$store.state.topId) }else{ this.$store.commit('stateFun',{ name: 'dataId', val: 0 }) } console.log("1111",item) this.$store.commit("stateFun",{ name:'testdataName', val:item.name }) var idx = this.model.indexOf(item); // console.log(this.model,idx,index) this.$set(this.model[idx], "show", !item.show); } } }; </script> <style lang="scss" scoped> * { box-sizing: border-box; margin: 0; padding: 0; } *:before, *:after { box-sizing: border-box; } ul, li { list-style: none; } .l_tree { calc(100% - 44px); /* height: 100%; */ padding-left: 31px; } .i_icon { display: inline-block; 19px; height: 19px; background-color: #00a0e9; font-size: 14px; text-align: center; color: #ffffff; outline: none; border: 0; text-align: center; line-height: 19px; cursor: pointer; } .l_tree_branch { 100%; height: 100%; display: block; padding: 13px; position: relative; } .l_tree_branch .l_tree_children_btn { 19px; height: 19px; background-color: #f5fbfe; font-size: 14px; text-align: center; color: #ffffff; outline: none; border: 0; cursor: pointer; } .l_tree_children_btn span i:nth-child(1) { color: #333; } ul.l_tree:before { content: ""; border-left: 1px dashed #999999; height: calc(100%); position: absolute; left: -1px; top: 0px; } .l_tree .l_tree_branch:last-child::before { content: ""; 3px; height: calc(100% - 24px); display: block; background-color: #f5fbfe; position: absolute; bottom: 0; left: -34px; } .l_tree, .l_tree_branch { position: relative; } .l_tree_branch::after { content: ""; 40px; height: 0; border-bottom: 1px dashed #000; position: absolute; right: calc(100% - 9px); top: 22px; } .l_tree_container > .l_tree::before, .l_tree_container > .l_tree > .l_tree_branch::after { display: none; } .l_folder { white-space: nowrap; cursor: pointer; /* margin-left: 16px; */ } .l_tree_click { white-space: nowrap; } </style>
调用:
<tree :model="testdata"></tree>
最后的效果:

如果要获取最后一级所在的是哪个父级,需要用反向递归实现:
obj表示完整的数据,name:表示当前的唯一标识,namePath:存放返回的数据
search(obj, name, namePath = []) {
for (let i = 0, len = obj.length; i < len; i++) {
let item = obj[i]
if (item.name === name) {
namePath.push(name)
item.expand = true
return {
has: true,
namePath
}
} else if (item.child && item.child.length) {
namePath.push(item.topId)
let result = this.search(item.child, name, namePath)
if (result.has) return {has: true, namePath}
namePath.pop()
}
}
return {
has: false
}
},