• vue 树形目录结构


     原先使用的是Ztree,后来因为更多的定制化要求,还是手写一个算了

    <template>
      <div>
        <menu-tree :nodes="nodes" :selected="currentCameraId"></menu-tree>
      </div>
    </template>
    
    <script>
    
      import EventBus from "@/utils/EventBus";
      import MenuTree from "@/views/HomePage2D/components/MenuTree";
      import dh_config from "static/config/dh-camera";
    
      export default {
        name: "zoneDeviceDir",
        components: {MenuTree},
        data() {
          return {
            nodes: [],
            allNodes: [],
            currentCameraId: ''
          }
        },
        watch: {},
        computed: {},
        methods: {
          //选中
          cameraClick(item) {
            this.currentCameraId = this.currentCameraId === item.id ? '' : item.id;
            if (this.currentCameraId !== '') {
              EventBus.$emit('showThisVideo',item)
            }
          },
          //全部展开或折叠
          allNoExpand(flag) {
            this.nodes.forEach(node => {
              this.noExpand(node, flag)
            })
          },
          noExpand(node, flag) {
            node.expand = flag;
            if (node.children && node.children.length > 0) {
              node.children.forEach(childNode => {
                this.noExpand(childNode, flag)
              })
            }
          },
          //反向定位
          reverseCamera(id) {
    
    
            this.currentCameraId = id;
            this.allNoExpand(false);
            this.nodes = this.allNodes;
            this.cameraSelect(this.nodes, id);
          },
          cameraSelect(nodes, queryData) {
            for (let i = 0; i < nodes.length; i++) {
              let node = nodes[i];
              if (node.children === null && this.corCamera(node, queryData)) {
                node.expand = true;
              } else {
                let deepQuery = this.corCamera(node, queryData);
                if (deepQuery) {
                  node.expand = true;
                  if (node.children) {
                    this.cameraSelect(node.children, queryData);
                  }
                }
              }
            }
          },
          corCamera(node, queryData) {
            if (node.children === null) {
              if (node.id === queryData) {
                return true;
              } else {
                return false;
              }
            }
            for (let i = 0; i < node.children.length; i++) {
              if (this.corCamera(node.children[i], queryData)) {
                return true;
              }
            }
            return false;
          },
          //查找
          search(queryData) {
            let array = this.treeSelect(this.allNodes, queryData);
            this.nodes = array;
            this.allNoExpand(true);
          },
          treeSelect(nodes, queryData) {
            let newArray = [];
            for (let i = 0; i < nodes.length; i++) {
              let node = nodes[i];
              if (node.children === null && this.treeDeepQuery(node, queryData)) {
                newArray.push(node);
              } else {
    
                let deepQuery = this.treeDeepQuery(node, queryData);
                if (deepQuery) {
                  let newNode = JSON.parse(JSON.stringify(node));
                  if (node.children) {
                    newNode.children = this.treeSelect(node.children, queryData);
                  }
                  newArray.push(newNode)
                }
              }
    
            }
            return newArray;
          },
          treeDeepQuery(node, queryData) {
            if (node.children === null) {
              if (node.name.indexOf(queryData) !== -1) {
                return true;
              } else {
                return false;
              }
            }
    
            for (let i = 0; i < node.children.length; i++) {
              if (this.treeDeepQuery(node.children[i], queryData)) {
                return true;
              }
            }
            return false;
          }
        },
        mounted() {
          EventBus.$on("item-click", this.cameraClick)
          EventBus.$on('ReversePositioning',this.reverseCamera)
          let T = this
          this.$axios.get(`/camera/menu/list?&time=${new Date().getTime()}`).then(res => {
            if (res.data.code !== 200) {
              this.$Message.error(res.data.msg)
            } else {
              T.nodes = res.data.data
              T.allNodes = res.data.data
            }
          })
        },
        beforeDestroy() {
        }
      }
    </script>
    
    <style lang="scss" scoped>
    </style>

    树组件

    <template>
      <div class="menu-tree" :class="{'menu-tree-top' : top}">
        <div v-for="item in nodes" :key="item.id">
          <!--菜单-->
          <div class="menu-item" @click="folderClick(item)" v-show="item.children !== null && item.num > 0">
            <div style="position: absolute;top: 0;left: 20px; calc(100% - 20px);height: 100%"></div>
              <i class="iconfont iconjia" v-show="!item.expand" style="color: #0ABBE5"></i>
              <i class="iconfont iconjian" v-show="item.expand"></i>
              {{item.name}}<span v-show="item.num > 0">({{item.num}})</span>
          </div>
          <!--摄像头-->
          <div class="menu-item" @click="itemClick(item)" v-show="item.children === null"  :class="{'menu-item-selected-parent':item.id === selected}">
            <div style="position: absolute;top: 0;left: 20px; calc(100% - 20px);height: 100%" :class="{'menu-item-selected':item.id === selected}"></div>
            <i class="iconfont iconshexiangtou" :class="[{'online': item.statusName === '在线'},{'offline': item.statusName !== '在线'}]"></i>
            <span>({{item.resource}})&nbsp;</span>{{item.name}}
          </div>
          <!--子菜单递归-->
          <div v-show="item.children && item.children.length > 0 && item.expand" class="child-menu">
            <menu-tree :nodes="item.children" :selected="selected" :top="false"></menu-tree>
          </div>
        </div>
      </div>
    </template>
    
    <script>
      import EventBus from "@/utils/EventBus";
    
      export default {
        props: {
          nodes: Array,
          selected: String,
          top: {
            required: false,
            default: true
          }
        },
        name: "MenuTree",
        data() {
          return {}
        },
        mounted() {
        },
        methods: {
          itemClick(item) {
            EventBus.$emit('item-click', item);
          },
          folderClick(item) {
            this.nodes.forEach(node => {
              if (node.id === item.id) {
                node.expand = !node.expand;
              }
            })
          }
        }
      }
    </script>
    
    <style lang="scss">
    
      .menu-tree {
        color: #333;
        font-size: 17px;
        position: relative;
    
        .menu-item {
          position: relative;
          padding-left: 25px;
          height: 40px;
          line-height: 40px;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
    
    
          .online {
            color: #1686D8;
          }
    
          .offline {
            color: #B7C3CE;
          }
    
          .menu-item-selected {
            border: 1px solid #1686D8;
            background: rgba(22, 134, 216, 0.1);
          }
    
    
          &:hover {
            cursor: pointer;
            > div {
              &:first-child {
                border: 1px solid #1686D8;
                background: rgba(22, 134, 216, 0.1);
              }
            }
          }
    
          &:after {
            content: "";
            width: 11px;
            height: 20px;
            position: absolute;
            left: 12px;
            top: 19px;
            border-width: 1px;
            border-top: 1px dashed #52627C;
          }
        }
    
        .menu-item-selected-parent {
          font-weight: bold;
        }
    
        .menu-item-camera {
          width: 100%;
        }
    
        .child-menu {
          margin-left: 20px;
          position: relative;
          &:before {
            content: "";
            height: calc(100% - 11px);
            width: 1px;
            position: absolute;
            left: 12px;
            top: -11px;
            border-width: 1px;
            border-left: 1px dashed #52627C;
          }
        }
      }
    
      .menu-tree-top > div > .menu-item {
        /*padding-left: 0;*/
        &:before {
          border-left: none;
        }
        &:after {
          border-top: none;
        }
      }
    </style>
  • 相关阅读:
    导出表结构语句
    closeChannel: close the connection to remote address[] result: true
    spingboot使用rabbitmq
    服务器很卡问题排查
    docker-compose安装nginx
    Docker方式安装ShowDoc
    "docker build" requires exactly 1 argument
    Intellij IDEA常用快捷键介绍 Intellij IDEA快捷键大全汇总
    IDEA 2018 3.4 激活破解方法
    jpress:v3.2.5的docker-compose安装
  • 原文地址:https://www.cnblogs.com/yangzhengier/p/14335862.html
Copyright © 2020-2023  润新知