码云地址(demo实例): gitee.com/big-sun/men…
- 调用目录树组件的父组件
<template>
<div id="app">
<wrap-left-slide
:menuarr="arr"
:selectindex="flagIndex"
@selectitem="selectItem"
>无限级目录树</wrap-left-slide>
</div>
</template>
<script>
import menuTree from "./components/recursice-tree/wrap-recursion.vue";
export default {
name: "App",
data() {
return {
flagIndex: "",
arr: [//数据源:注意数据格式,不能乱写
{
name: "主要职责1",
mark: "8142754caa2a4e01bed712888bb5be3c",
pid: "main-responsibilities",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
]
};
},
components: {
"wrap-left-slide": menuTree
},
mounted(){
setTimeout(() => {
this.flagIndex='ab228h99bg6d28274b13c183fab3ga5a';
this.arr=[//这个结构很关键,子项的pid需要等于父项的mark(牢记)
{
name: "主要职责",
mark: "8142754caa2a4e01bed712888bb5be3c",
pid: "main-responsibilities",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "内设机构",
mark: "10b14bfc399c42e2b88b98a95855df3d",
pid: "Internal-organization",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "主要负责人",
mark: "e41a3dcc76db467a912d9b828c87fbfc",
pid: "principal-responsible-person",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "训练基地",
mark: "d945a2c553c243c0b6d515ad89bd6d0d",
pid: "training-base",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "联系方式",
mark: "8e2a990e6b354d69b3ca631675ab2b43",
pid: "contact-information",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "考察船",
mark: "004001001",
pid: "observation-station",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline",
children: [
{
name: "雪龙2号",
mark: "22cd30d7444f4f4399341ad5586768ed",
pid: "004001001",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline",
children: [
{
name: "船只介绍",
mark: "hhd81e26ha3h46d86cgd44e6f2bh93hc",
pid: "22cd30d7444f4f4399341ad5586768ed",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "建造过程",
mark: "ad18bf9f3g5bh8962d9e6g2ha1b1d219",
pid: "22cd30d7444f4f4399341ad5586768ed",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "船只特点",
mark: "4h4522d8f11b413cef3de47df139hd72",
pid: "22cd30d7444f4f4399341ad5586768ed",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "性能参数",
mark: "haf51b26932d2c727a9a9bba11c5cc16",
pid: "22cd30d7444f4f4399341ad5586768ed",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "性能参数",
mark: "ac142g16h7g942eafea65f54772dh7e3",
pid: "22cd30d7444f4f4399341ad5586768ed",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "船只功能",
mark: "23938776f74c7392cad6h4hg966b6712",
pid: "22cd30d7444f4f4399341ad5586768ed",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "船只设计",
mark: "ccchcc6b5c625fc24c1d68977ad3ahb7",
pid: "22cd30d7444f4f4399341ad5586768ed",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "航行试验",
mark: "ab228h99bg6d28274b13c183fab3ga5a",
pid: "22cd30d7444f4f4399341ad5586768ed",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "科学考察",
mark: "4b3bcahh85315b22a96d4edgbhdg4h44",
pid: "22cd30d7444f4f4399341ad5586768ed",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "最新消息",
mark: "f61fb214c833985a4fe527g8g9fc2517",
pid: "22cd30d7444f4f4399341ad5586768ed",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "建造意义",
mark: "bd9c153hbeead137g2f13636g77955d2",
pid: "22cd30d7444f4f4399341ad5586768ed",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
}
]
},
{
name: "雪龙一号",
mark: "4fd5c71775ef4cd78ef396049e7efb95",
pid: "004001001",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
}
]
},
{
name: "考察站",
mark: "004001002",
pid: "survey-ship",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline",
children: [
{
name: "罗斯海新站",
mark: "011f3979b66b4b858d502b88a4e3125c",
pid: "004001002",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline",
children: [
{
name: "建设沿革",
mark: "44c1ec526gdf6878a8g29177bage43bh",
pid: "011f3979b66b4b858d502b88a4e3125c",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "地理位置",
mark: "7g1ce29315chcf9e7683ge829a9aah49",
pid: "011f3979b66b4b858d502b88a4e3125c",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "建设意义",
mark: "b9g3a2h619g26e7gb1f3dg614f27f2g8",
pid: "011f3979b66b4b858d502b88a4e3125c",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "建设历程",
mark: "34894b3e2g2g6adg6a55497g256g8ed4",
pid: "011f3979b66b4b858d502b88a4e3125c",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "站点工作",
mark: "6244f76be38fe16616adeah975e7hdb7",
pid: "011f3979b66b4b858d502b88a4e3125c",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
}
]
},
{
name: "泰山站",
mark: "ba5b63c95aa54bbebe90779b71864d28",
pid: "004001002",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "昆仑站",
mark: "3e8edfc37af14496b5bcd48e098f0ac9",
pid: "004001002",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "黄河站",
mark: "f530c149353a43cdbce1af2034cb25ed",
pid: "004001002",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "中山站",
mark: "89c74e44d1c34b0b85791e6997e9f840",
pid: "004001002",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
},
{
name: "长城站",
mark: "cee27231146d40a293b6aac5226fa5fe",
pid: "004001002",
headerIconActive: "el-icon-user-solid",
headerIconNormal: "el-icon-user",
footerIconActive: "el-icon-warning",
footerIconNormal: "el-icon-warning-outline"
}
]
}
]
}, 2000);
},
methods: {
selectItem(item) {
console.log(item);
}
}
};
</script>
<style lang='scss'>
@import url("./assets/normalize.css");
ul{
margin: 0;
padding: 0;
list-style: none;
}
</style>
- .wrap.-recursion.vue文件
<template>
<div class="wrapRecursion">
<p class="wrapboxheaderstyle">
<slot>目录树标题</slot>
</p>
<left-slide
:menuarr="arr"
:selectindex="flagIndex"
:depth="depth"
@selectitem="selectitem"
></left-slide>
</div>
</template>
<script>
import recursion from "./recursion";
export default {
name: "wrapRecursion",
props: {
menuarr: {
type: Array,
required: true
},
selectindex: {
type: [String, Number],
required: true
},
depth: {
type: Number,
default: 1.2
},
shiftIconBool: {
type: Boolean,
default: false
}
},
data() {
return {
msg: "外包装递归组件",
arr: [],
flagIndex: ""
};
},
components: {
"left-slide": recursion
},
watch: {
menuarr: {//实时监听异步返回来的数据
handler(newName, oldName) {
if (newName.length == this.menuarr.length) {
this.arr = newName;
this.flagIndex = this.selectindex;
this.init(this.arr, this.flagIndex);
}
}
}
},
created() {
this.arr = this.menuarr;
this.flagIndex = this.selectindex;
this.init(this.arr, this.flagIndex);
},
methods: {
addLock(arr) {//锁
arr.forEach(item => { //工具函数-给数据数组中每一个对象都关锁
this.$set(item, "lock", false);
if (this.shiftIconBool) {//添加icon图标
this.$set(item, "headerIcon", item.headerIconNormal||"el-icon-help");
this.$set(item, "footerIcon", item.footerIconNormal||"el-icon-circle-plus-outline");
}
if (!!item.children) {
this.addLock(item.children);
}
});
},
getParentNode(arr, mark, temp) {//工具函数-将数组中符合mark的对象放到一个新数组中
for (var i = 0; i < arr.length; i++) {
let item = arr[i];
if (item.mark == mark) {
temp.unshift(item);
this.getParentNode(this.arr, item.pid, temp);
break;
} else {
if (!!item.children) {
this.getParentNode(item.children, mark, temp);
}
}
}
return temp;
},
init(arr, mark) {//初始化数据
this.addLock(arr); //上锁
this.getParentNode(arr, mark, []).forEach(item => {//部分开锁
this.$set(item, "lock", true);
if (this.shiftIconBool) {//添加icon图标
this.$set(item, "headerIcon", item.headerIconActive||"el-icon-s-help");
this.$set(item, "footerIcon", item.footerIconActive||"el-icon-remove");
}
});
},
selectitem(item) {
if (item.mark == this.flagIndex) {//点击的是同一个item
this.$set(item, "lock", !item.lock);
if (this.shiftIconBool) {
if (item.lock) {
this.$set(item, "headerIcon", item.headerIconActive||"el-icon-s-help");
this.$set(item, "footerIcon", item.footerIconActive||"el-icon-remove");
} else {
this.$set(item, "headerIcon", item.headerIconNormal||"el-icon-help");
this.$set(item, "footerIcon", item.footerIconNormal||"el-icon-circle-plus-outline");
}
}
} else {//点击的不是同一个item
this.addLock(this.arr);//上锁
this.getParentNode(this.arr, item.mark, []).forEach(item => {//部分开锁
this.$set(item, "lock", true);
if (this.shiftIconBool) {
this.$set(item, "headerIcon", item.headerIconActive||"el-icon-s-help");
this.$set(item, "footerIcon", item.footerIconActive||"el-icon-remove");
}
});
this.getParentNode(this.arr, this.flagIndex, []).forEach(value => {//找到上一个选中的item关闭它
if (value.mark == item.mark) {
this.$set(item, "lock", false);
if (this.shiftIconBool) {
this.$set(item, "headerIcon", item.headerIconNormal||"el-icon-help");
this.$set(item, "footerIcon", item.footerIconNormal||"el-icon-circle-plus-outline");
}
}
});
}
this.flagIndex = item.mark;
this.$emit("selectitem", item);
}
}
};
</script>
<style scoped src='./wrap-recursion.css'></style>//自定义的css样式(设置目录树的标题)
- recursion.vue文件
<template>
<ul class="left-slide">
<li
v-for="(item,index) in menuarr"
:key="index"
>
<p
class="menuItem"
:style="paddingLeft"
:class="{active:item.mark==selectindex}"
@click="selectitem(item)"
:title="item.name"
>
<span :class="item.headerIcon"></span>
<span>{{item.name}}</span>
<span
v-if="item.children"
:class="item.footerIcon"
></span>
</p>
<el-collapse-transition>
<left-slide
v-if="item.children && item.lock"
:menuarr="item.children"
:selectindex="selectindex"
@selectitem="selectitem"
:depth="depth+1.5"
></left-slide>
</el-collapse-transition>
</li>
</ul>
</template>
<style scoped lang='scss'>
.menuItem {//单号阶段
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
<style scoped src='./recursion.css'></style>//用户自定义目录树中每一项的样式
<script>
export default {
name: "left-slide",
props: {
menuarr: {
type: Array,
required: true
},
selectindex: {
type: [String, Number],
required: true
},
depth: {
type: Number,
default: 0
}
},
data() {
return {
msg: "左侧目录导航栏"
};
},
created() {},
computed: {
paddingLeft() {
return `padding-left: ${this.depth * 10}px`;
}
},
mounted() {},
methods: {
selectitem(item) {
//监听item的点击
this.$emit("selectitem", item);
}
}
};
</script>