<template>
<view class="container" :style="{ 'min-height': comMinHeight }">
<view class="treeBox">
<view
v-for="node in treeList"
:key="node.id"
class="treeitem"
@click="changeShow(node, isOpen(node.id), node.childrenId)"
>
<view class="box df jcss">
<block
v-if="
node.childrenId &&
node.childrenId.length > 0 &&
(node.parentId.length === 0 || isShow(node.id))
"
>
<image
class="img"
:style="{ marginLeft: `${node.num * 30}rpx` }"
:src="isOpen(node.id) ? bottom : right"
/>
</block>
<view
v-if="node.parentId.length === 0 || isShow(node.id)"
class="checkout"
:style="{
marginLeft: !node.childrenId ? `${24 + node.num * 30}rpx` : '',
}"
>
<checkbox
color="white"
:value="node.id"
:checked="node.ischecked"
style="transform: scale(0.6)"
disabled
/><text>{{ node.label }}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { getStorage } from "@/utils/auth";
import bottom from "../../subPack/static/image/bottom.png";
import right from "../../subPack/static/image/right.png";
export default {
props: ["status", "minHeight", "productPageInfo", "shopCode"],
data() {
return {
dataList: getStorage("userInfo").role[0].menuTreeSelect,
bottom,
right,
openList: [], // 展开节点数组(只存放带有子级的节点)
checkedList: ["1590589009279098881"], // 当前选中节点数组
treeList: [], // 扁平化后的树数据源
showList: [], // 当前展示的树节点(0级节点默认添加到数组中始终显示,其他级别动态控制显隐)
data: [
{
id: 123,
label: "首页",
children: [
{ id: 234, label: "测试" },
{ id: 432, label: "数据" },
],
},
{
id: 543,
label: "我的",
children: [
{ id: 654, label: "测试1" },
{ id: 542, label: "数据2" },
],
},
],
};
},
computed: {
isOpen() {
return function (key) {
return this.openList.includes(key);
};
},
isShow() {
return function (key) {
return this.showList.includes(key);
};
},
},
watch: {},
created() {
this.get();
},
methods: {
// 扁平化数据
get() {
this.treeList = getListByTree(this.dataList);
function getListByTree(data) {
const treeList = [];
const getData = function (
list = [],
num = 0,
parents = [],
parentId = []
) {
list.forEach((item) => {
const node = {
parents,
parentId,
num,
id: item.id,
label: item.label,
source: item,
ischecked: false,
};
if (item.children && item.children.length > 0) {
let parentid = [...parentId];
let parentArr = [...parents];
parentArr.push({
id: item.id,
label: item.label,
});
parentid.push(item.id);
node.childrenId = [];
item.children.forEach((i) => node.childrenId.push(i.id));
treeList.push(node);
getData(item.children, num + 1, parentArr, parentid);
} else {
treeList.push(node);
}
});
};
getData(data);
return treeList;
}
// this.treeList.forEach((i) => {
// if (i.childrenId && i.childrenId.length > 0) {
// i.childrenId.forEach((x) => {
// i.childrenId.push(i.id + "-" + x);
// });
// }
// });
this.controlIsChecked(this.checkedList, true);
},
// 设置是否选中
controlIsChecked(list, falg) {
this.treeList.forEach((i) => {
if (list.includes(i.id)) {
i.ischecked = falg;
}
});
},
//点击打开 关闭
changeShow(item, show, hasChildren) {
if (!hasChildren) return;
const _this = this;
if (show) {
// 先过滤掉点击的元素
_this.openList = [...this.delteItem(_this.openList, item.id)];
//关闭的节点
let close = [
...new Set(this.generationKeys(item.childrenId, this.treeList)),
];
close.forEach((c) => {
// 将关闭节点的子级全部隐藏
this.showList = this.showList.filter((k) => k !== c);
this.openList = this.delteItem(_this.openList, c);
});
} else {
this.showList.push(...item.childrenId);
this.openList.push(item.id);
}
},
//如果子集还有子集,全部取出来
generationKeys(children, treeList) {
let checkedKeys = [];
const getKeys = (ids, list) => {
ids.forEach((child) => {
const childNode = list.find((tree) => tree.id === child);
if (childNode && childNode.childrenId) {
getKeys(childNode.childrenId, treeList);
checkedKeys = [...checkedKeys, child, ...childNode.childrenId];
} else {
checkedKeys = [...checkedKeys, child];
}
});
};
getKeys(children, treeList);
return checkedKeys;
},
// 删除指定的元素
delteItem(arr, item) {
let newArr = arr;
let index = newArr.findIndex((n) => {
return n == item;
});
if (index >= 0) {
newArr.splice(index, 1);
}
return newArr;
},
},
};
</script>
<style lang="scss" scoped>
.container {
font-size: 24rpx;
.img {
width: 24rpx;
height: 24rpx;
display: inline-block;
margin: auto 0rpx;
}
.treeitem {
line-height: 60rpx;
}
}
</style>
tree vue
最新推荐文章于 2024-07-15 17:15:41 发布