tree vue

<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>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值