原先使用的是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;width: 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;width: 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}}) </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>