树形结构菜单,递归实现

这是原网址: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 { width: calc(100% - 44px); /* height: 100%; */ padding-left: 31px; } .i_icon { display: inline-block; width: 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 { width: 100%; height: 100%; display: block; padding: 13px; position: relative; } .l_tree_branch .l_tree_children_btn { width: 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: ""; width: 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: ""; width: 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
      }
    },

  

猜你喜欢

转载自www.cnblogs.com/js-liqian/p/12027347.html