vue递归组件简单实现一个树形组件

<template>
  <div class="list-wrap">
    <div
      v-for="item of list"
      :key="item.title"
      class="item"
    >
      <div
        class="item-title-wrap"
        @click="onItemClick(item)"
      >
        <div class="item-title">{{item.title}}</div>
        <i
          class="iconfont arrow"
          :class="{'up-arrow': item.unfolded}"
          v-if="item.children"
          @click.stop="onArrowClick(item)"
        >&#xe61a;</i>
      </div>
      <transition name="fade">
        <div
          v-if="item.children && item.unfolded"
          class="item-children"
          :key="item.title"
        >
         //在CaseList中自己调用自己
          <case-list :list="item.children"></case-list>
        </div>
      </transition>
    </div>
  </div>
</template>

<script>
//生成器函数遍历数据
function* traversalData(data) {
  for (let i = 0; i < data.length; i++) {
    yield data[i];
    if (data[i].children) {
      yield* traversalData(data[i].children);
    }
  }
}

export default {
//通过name属性递归调用自己
  name: "CaseList",
  components: {},
  props: {
    list: Array
  },
  data() {
    return {};
  },
  computed: {
    newList: {
      get() {
        return this.list;
      },
      set() {}
    }
  },
  methods: {
    onItemClick(item) {
      console.log(item, "item click");
    },
    onArrowClick(item) {
      const newList = this.newList;
      for (let caseItem of traversalData(newList)) {
//通过unfolded表示展开折叠
        if (caseItem.title === item.title && !caseItem.unfolded) {
          caseItem.unfolded = true;
        } else {
          caseItem.unfolded = false;
        }
      }
      console.log(item, newList, "arrow click");
    }
  }
};
</script>

<style lang="less" scoped>
.list-wrap {
  position: relative;
  .item-title-wrap {
    display: flex;
    align-items: center;
    margin-bottom: 10px;
    .arrow {
      position: absolute;
      right: -100px;
      transition: all 0.3s;
    }
    .up-arrow {
      transform: rotate(180deg);
    }
  }
}

.item-children {
  padding-left: 15px;
}

.fade-enter,
.fade-leave-to {
  opacity: 0;
}
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s;
}
</style>

//数据结构如下
list: [
        {
          title: "文件库",
          count: "99",
          children: [
            {
              title: "文件夹1",
              count: "66",
              children: [
                {
                  title: "文件夹5",
                  count: "66",
                  children: [
                    {
                      title: "文件1"
                    }
                  ]
                }
              ]
            },
            {
              title: "文件夹2",
              count: "33",
              children: [{ title: "文件2" }]
            }
          ]
        },
        {
          title: "默认文件夹",
          count: "33",
          children: [
            {
              title: "文件夹3",
              count: "22",
              children: [{ title: "文件3" }]
            },
            {
              title: "文件夹4",
              count: "11",
              children: [{ title: "文件4" }]
            }
          ]
        }
      ]

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值