Vue 遞歸實現樹形結構

結果展現

先給出兩張效果圖,左側是百度Echarts的文檔中心截圖,右側是我我的結合項目中文檔中心截圖 百度Echarts的文檔中心我的總結文檔中心前端

  • 項目中假設爲後臺管理系統,通常左側導航都是樹形遞歸,固然如今也有不少的UI框架,隨便套一下也是能夠用的;
  • 樓主這裏要總結的是vue組件化的時候,當前樹形結構組件自行調用;
  • 僅供項目總結,若有不對的地方,請多多包涵。

代碼結構

  • mTree.vue
<template>
        <li class="tree-items"
              :class="{'active':model.path === this.$route.params.filePath}">
            <a class="item-title"
               @click="toggle(model)"
               :class="{'item-hover': model.type === 'file'}">
              {{ model.name }}
          <span
               class="item-icon"
               :class="{'openmenu': open}"
               v-if="model.type !== 'file'">
          </span>
          </a>
        <ul v-show="open" v-if="model.type === 'directory'" class="child-list-box">
          <m-tree v-for="item in model.files" :model="item" :key="item.name"></m-tree>
        </ul>
     </li>
</template>

<script>
  export default {
    name: 'mTree',
    props: ['model', 'index'],
    data() {
      return {
        open: true
      }
    },
    methods: {
      toggle: function (model) {
        let self = this;
        if (model.type === "directory") {
          this.open = !this.open;
        } else {
          console.log('file');
        }
      }
    }
  }
</script>

<style lang="less">
  .tree-items {
    margin: 8px 0 0 0;
    padding: 3px;
    color: #575d6f;
    border-radius: 5px;
    cursor: pointer;
    user-select: none;
    &.active {
      .item-title {
        color: #1357ba;
      }
    }
    &.onHitClass {
      background-color: #dbdce0;
    }
    .item-title {
      line-height: 1px;
      font-size: 16px;
      font-weight: bold;
      color: #575d6f;
      &.item-hover {
        &:hover {
          color: #1357ba;
        }
      }
    }
    .item-icon {
      display: inline-block;
      transform: rotate(-180deg);
      margin-left: 12px;
      width: 7px;
      height: 7px;
      background: url('三角形的圖片.png') no-repeat center;
      transition: all .3s;
      &.openmenu {
        transform: rotate(0deg);
      }
    }
    .child-list-box {
      padding-left: 17px;
      .tree-items {
        margin: 5px 0;
        color: #666;
        text-decoration: none;
        display: block;
        font-weight: 300;
        padding: 4px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        .item-title {
          font-size: 14px;
          margin-bottom: 12px;
          font-weight: normal;
        }
      }
    }
  }
</style>
  • mDemo.vue
<template>
       <div class="doc-center-wrap">
           <div class="doc-center-slide">
              <div class="doc-center-searbox">
                    <span class="doc-center-searimg"></span>
                    <Input size="large" placeholder="請輸入關鍵字" @on-keyup="searchKeywords" v-model="keywords"/>
              </div>
              <div class="doc-center-tree" id="tree-slide">
                    <ul class="tree-menu-ul" v-for="(menuItem, index) in treeModel" :key="index">
                        <m-tree :model="menuItem" :index="index"></m-tree>
                    </ul>
              </div>
           </div>
      </div>
</template>

<script>
    import MTree from "./mTree.vue";
    let data =  [{
		"type": "file",
		"name": "前端框架",
		"path": "about"
	}, {
		"type": "file",
		"name": "前端框架",
		"path": "guide"
	}, {
		"type": "file",
		"name": "前端框架",
		"path": "zip-guide"
	}, {
		"type": "file",
		"name": "UI模塊引擎",
		"path": "remote-debugging"
	},
	{
		"type": "directory",
		"name": "雲API",
		"files": [{
			"type": "file",
			"name": "數據雲API",
			"path": "component-album"
		}, {
			"type": "file",
			"name": "數據雲API",
			"path": "component-app"
		}]
	}
]  

let fileFrist = [];
  function showFristFile(data) {
    for (let i in data) {
      let fileModel = data[i];
      if (fileModel.type === "file") {
        fileFrist.push(fileModel);
      } else {
        showFristFile(fileModel.files);
      }
    }
    return fileFrist;
  }

    export default {
        data(){
            return {
                   treeModel:   data,
                   retrievalWords: showFristFile(data),
                    keywords:''
            }
        },
        components: {
          MTree
        },
        methods:{
             searchKeywords() {
        let self = this;
        let retrievalWords = self.retrievalWords;
        let keywords = self.keywords;
        if (!keywords) {
          self.treeModel= self.treeModel;
        } else {
          let arrKeywords = [];
          for (let i = 0; i < retrievalWords.length; i++) {
            if (retrievalWords[i].name.toLowerCase().indexOf(keywords.toLowerCase()) !== -1) {
              arrKeywords.push(retrievalWords[i]);
            }
          }
          self.treeModel = arrKeywords;
        }
      }
        }
    }
</script>

總結

  • 整理的有點雜亂,有空從新整理一下,而且貼出完整的代碼
  • 項目總結,請多多包涵。
相關文章
相關標籤/搜索