vue实现目录树结构

Fredrica ·
更新时间:2024-09-20
· 1300 次阅读

本文实例为大家分享了vue实现目录树结构的具体代码,供大家参考,具体内容如下

效果图

代码

组件部分 components/leftTree.vue

<template>     <div>         <ul class="all-list">             <li v-for="(item, i) in list" :key="item.key">             <!-- Antd的双击功能 这个看个人需求,不需要的话把'<div class="tree-item expend></div>'提取出来就可以了 -->               <a-dropdown :trigger="['contextmenu']">                 <a-menu slot="overlay">                   <a-menu-item key="1">                     打开文件                   </a-menu-item>                   <a-menu-item key="2">                     新建文件                   </a-menu-item>                   <a-menu-item key="3">                     保存                   </a-menu-item>                   <a-menu-item key="4">                     删除                   </a-menu-item>                 </a-menu>                 <div class="tree-item expend">                     <div                         v-if="item.icon === 'file' || item.icon === 'openfile'"                         class="icon-size"                         :class="                             openArr.includes(i) ? 'reduce-icon' : 'expend-icon'                         "                         @click="toggle(i)"                     ></div>                     <i v-if="item.icon === 'file'"                         ><img src="../assets/file.png"                     /></i>                     <i v-if="item.icon === 'openfile'"                         ><img src="../assets/openfile.png"                     /></i>                     <i v-if="item.icon === 'vue'"                         ><img src="../assets/Vue.png"                     /></i>                     <i v-if="item.icon === 'js'"                         ><img src="../assets/js.png"                     /></i>                     <i v-if="item.icon === 'react'"                         ><img src="../assets/React.png"                     /></i>                     <i v-if="item.icon === 'sass'"                         ><img src="../assets/Sass.png"                     /></i>                      <i v-if="item.icon === 'vim'"                         ><img src="../assets/vimeo.png"                     /></i>                      <i v-if="item.icon === 'ts'"                         ><img src="../assets/ts.png"                     /></i>                      <i v-if="item.icon === 'php'"                         ><img src="../assets/php.png"                     /></i>                     <i v-if="item.icon === 'less'"                         ><img src="../assets/less.png"                     /></i>                     <i v-if="item.icon === 'java'"                         ><img src="../assets/java.png"                     /></i>                     <i v-if="item.icon === 'c++'"                         ><img src="../assets/c++.png"                     /></i>                     <i v-if="item.icon === 'markdown'"                         ><img src="../assets/markdown.png"                     /></i>                     <i v-if="item.icon === 'py'"                         ><img src="../assets/py.png"                     /></i>                     <i v-if="item.icon === 'go'"                         ><img src="../assets/go.png"                     /></i>                     <span class="content" @click="changeActive(item, i)">{{                         item.title                     }}</span>                 </div>               </a-dropdown>                 <!-- 递归 -->                 <div                     v-show="openArr.includes(i)"                     v-if="item.children && item.children.length"                 >                     <leftTree class="item" :list="item.children"></leftTree>                 </div>             </li>         </ul>     </div> </template> <script> export default {     name: "leftTree",     data() {         return {             openArr: [],             checkboxIds: [],         };     },     props: {         list: {             type: Array,         },     },     methods: {         toggle(i) {             if (this.openArr.includes(i)) {                 let index = this.openArr.indexOf(i);                 this.openArr.splice(index, 1);             } else {                 this.openArr.push(i);             }         },         changeActive(item, i) {             if (!item.children) {                 if (item.icon === "file") {                     this.toggle(i);                     item.icon = "openfile";                 } else if (item.icon === "openfile") {                     this.toggle(i);                     item.icon = "file";                 } else {                     alert("最后一个文件");                 }             } else {                 if (item.icon === "file") {                     this.toggle(i);                     item.icon = "openfile";                 } else if (item.icon === "openfile") {                     this.toggle(i);                     item.icon = "file";                 }             }         },     }, }; </script> <style lang='less' scoped> i {     line-height: 0;     img {       width: 16px;       height: 16px;     } } .item {     padding-left: 4px; } .bold {     font-weight: bold; } ul {     line-height: 1.5em;     list-style-type: none;     white-space: nowrap;     position: relative; } li {     list-style-type: none;     padding: 4px;     user-select: none; } .tree-item {     display: flex;     align-items: center; } .expend {     position: relative; } .expend::before {     content: "";     position: absolute;     width: 6px;     left: 9px;     top: 10px;     border-top: 1px dotted #c3c5c8; } .all-list::before {     content: "";     position: absolute;     width: 1px;     height: calc(100% - 40px);     left: 48px;     top: 20px;     border-left: 1px dotted #c3c5c8; } .item .expend::before {     content: "";     position: absolute;     width: 6px;     left: -11px;     top: 10px;     border-top: 1px dotted #c3c5c8; } .item .all-list::before {     content: "";     position: absolute;     width: 1px;     height: calc(100% - 12px);     left: 20px;     top: 0;     border-left: 1px dotted #c3c5c8; } .item ul {     padding-left: 2em; } .content {     padding-left: 4px;     transition: all 0.2s linear;     &:hover {       background: #c3c5c8;     } } .spacing {     display: inline-block;     width: 18.5px;     height: 1em; } .icon-size {     display: inline-block;     width: 16px;     height: 16px;     margin-right: 4px; } .expend-icon {     background: url("../assets/Plus.png") no-repeat center;     background-size: cover;     width: 9px;     height: 9px; } .reduce-icon {     background: url("../assets/minus.png") no-repeat center;     background-size: cover;     width: 9px;     height: 9px; } .ant-dropdown-menu {   width: 180px;   background: #353b44;   li {     color: #fff;     padding: 2px 10px;     &:hover {       background: rgb(13, 89, 175);     }   } } </style>

引用区域 views/home.vue

<template>     <div class="home">         <tree :list="line" />     </div> </template> <script> import tree from "@/components/leftTree.vue"; export default {     name: "Home",     components: {         tree,     },     data() {         return {             line: [                 {                     title: "Project",                     type: 1,                     key: "1",                     icon: "file",                     children: [                         {                             title: "index.vim",                             key: "1-1",                             type: 3,                             icon: "vim",                         },                     ],                 },                 {                     title: "Menu",                     type: 1,                     key: "2",                     icon: "file",                 },                 {                     title: "Components",                     type: 1,                     key: "3",                     icon: "file",                     children: [                         {                             title: "Index",                             type: 2,                             key: "3-1",                             icon: "file",                             children: [                                 {                                     title: "index.vue",                                     type: 3,                                     key: "3-1-1",                                     icon: "vue",                                 },                                 {                                     title: "index.react",                                     type: 3,                                     key: "3-1-2",                                     icon: "react",                                 },                                 {                                     title: "js",                                     type: 2,                                     key: "3-1-3",                                     icon: "file",                                     children: [                                         {                                             title: "index.js",                                             type: 3,                                             key: "3-1-1-1-1",                                             icon: "js",                                         },                                     ],                                 },                                 {                                     title: "index.sass",                                     type: 3,                                     key: "3-1-4",                                     icon: "sass",                                 },                                 {                                     title: "index.less",                                     type: 3,                                     key: "3-1-5",                                     icon: "less",                                 },                             ],                         },                         {                             title: "index.php",                             type: 3,                             key: "3-2",                             icon: "php",                         },                     ],                 },                 {                     title: "node_modules",                     type: 1,                     key: "4",                     icon: "file",                     children: [                         {                             title: "index.java",                             key: "4-1",                             type: 3,                             icon: "java",                         },                         {                             title: "index.go",                             key: "4-2",                             type: 3,                             icon: "go",                         },                         {                             title: "index.py",                             key: "4-3",                             type: 3,                             icon: "py",                         },                         {                             title: "index.c",                             key: "4-4",                             type: 3,                             icon: "c++",                         },                         {                             title: "README.md",                             key: "4-5",                             type: 3,                             icon: "markdown",                         },                     ],                 },             ],         };     }, }; </script>

ps: 本人是前端小白,发帖只是为了做笔记,代码可能有很多的优化空间,另外也希望可以帮助到其他有需要的朋友



VUE 树结构

需要 登录 后方可回复, 如果你还没有账号请 注册新账号