赞
踩
<template> <div class="main-sidebar" class="showSlide expandSide"> <el-menu class="el-menu-style" @select="" @open="handleOpen" @close="handleClose"> <template v-for="item in fileList"> <sub-menu :param="item" ></sub-menu> </template> </el-menu> </div> </template> <script> import subMenu from "./subMenu.vue" import {fileList} from '../http/api' export default { data() { return { fileList:{}, } }, computed: { onRoutes(){ return this.$route.path; }, onRouteKeys(){ return getParentArray(this.$route.path, this.fileList); } }, created() { this.loadFile(); }, methods: { handleOpen(key, keyPath) { }, handleClose(key, keyPath) { }, loadFile(){ let projectId = this.$route.params.id fileList(projectId).then(res => { this.fileList = res.data }).catch(err => { alert("当前用例为空") }) } } } </script> <style scoped> .showSlide { animation-duration: .2s; animation-name: slideInLeft; } .hideSlide { animation-duration: .2s; animation-name: slideOutLeft; } .main-sidebar { background-color: #ffffff; position: fixed; top: 50px; left: 0; bottom: 0; height: calc(100vh - 50px); width: 44px; z-index: 810; -webkit-transition: -webkit-transform 0.3s ease-in-out, width 0.3s ease-in-out; -moz-transition: -moz-transform 0.3s ease-in-out, width 0.3s ease-in-out; -o-transition: -o-transform 0.3s ease-in-out, width 0.3s ease-in-out; transition: transform 0.3s ease-in-out, width 0.3s ease-in-out; } .expandSide { width: 280px; } .el-menu-style, .el-menu-style .el-menu{ background-color: #ffffff; } .el-menu-style .el-menu-item:hover, .el-menu-style .el-submenu__title:hover{ background-color: #eeeeee !important; } .el-menu-style .el-submenu .el-menu-item { height: 45px; line-height: 45px; } .el-menu-style .el-menu-item, .el-menu-style .el-submenu__title { height: 45px; line-height: 45px; } .main-sidebar .el-menu--collapse { width: 44px; } .main-sidebar .el-menu--collapse>.el-menu-item, .main-sidebar .el-menu--collapse>.el-submenu>.el-submenu__title { padding-left: 13px !important; } .vue-scrollbar{ background-color: #ffffff !important; height: calc(100vh - 50px) } .main-sidebar .el-scrollbar__bar.is-vertical{ display: none; } .sidebar{ min-height: 450px; } </style>
<template> <div class="contents"> <div class="menu-list"> <el-submenu :index="item.href" v-if="item.children && item.children.length>0" class="el-menu-sub" > <template slot="title"> <div v-if="item.isShow == 2" v-contextmenu:contextmenu-file> <i class="fa fa-file"></i> <el-link :underline="false" @click="intoItem(item.id)"> <span>{{item.name}}</span> </el-link> </div> <div v-else v-contextmenu:contextmenu-folder> <i class="fa fa-folder"></i> <span>{{item.name}}</span> </div> </template> <template v-for="child in item.children"> <sub-menu v-if="child.children && child.children.length>0" :param="child"></sub-menu> <el-menu-item :index="child.href" v-else > <div v-if="child.isShow == 1" v-contextmenu:contextmenu-folder> <i class="fa fa-folder"></i> <span>{{item.name}}</span> </div> <div v-else v-contextmenu:contextmenu-file> <i class="fa fa-file"></i> <el-link :underline="false" @click="intoItem(child.id)"> <span>{{child.name}}</span> </el-link> </div> </el-menu-item> </template> </el-submenu> <el-menu-item :index="item.href" v-else class="el-menu-each"> <div v-if="item.isShow == 2" v-contextmenu:contextmenu-file> <i class="fa fa-file"></i> <el-link :underline="false" @click="intoItem(item.id)"> <span>{{item.name}}</span> </el-link> </div> <div v-else v-contextmenu:contextmenu-folder> <i class="fa fa-folder"></i> <span>{{item.name}}</span> </div> </el-menu-item> </div> </div> </template> <script> import subMenu from "./subMenu.vue" export default { name: 'subMenu', props: ['param'], data() { return { item: this.param } }, components: { subMenu, } } </script> <style scoped> .el-menu .fa { margin-right: 10px; } .box { width: 100%; } .el-dialog{ display: flex; flex-direction: column; margin:0 !important; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); /*height:600px;*/ max-height:calc(100% - 30px); max-width:calc(100% - 30px); } .el-dialog .el-dialog__body{ flex:1; overflow: auto; } </style>
.ztree * { moz-user-select: -moz-none; -moz-user-select: none; -o-user-select:none; -khtml-user-select:none; -webkit-user-select:none; -ms-user-select:none; user-select:none; padding:0; margin:0; font-size:12px; font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif} .ztree {margin:0; padding:5px; color:#333} .ztree li{padding:0; margin:0; list-style:none; line-height:17px; text-align:left; white-space:nowrap; outline:0} .ztree li ul{ margin:0; padding:0 0 0 18px} .ztree li ul.line{ background:url(../img/line_conn.png) 0 0 repeat-y;} .ztree li a {padding-right:3px; margin:0; cursor:pointer; height:21px; color:#333; background-color: transparent; text-decoration:none; vertical-align:top; display: inline-block} .ztree li a:hover {text-decoration:underline} .ztree li a.curSelectedNode {padding-top:0px; background-color:#e5e5e5; color:black; height:21px; opacity:0.8;} .ztree li a.curSelectedNode_Edit {padding-top:0px; background-color:#e5e5e5; color:black; height:21px; border:1px #666 solid; opacity:0.8;} .ztree li a.tmpTargetNode_inner {padding-top:0px; background-color:#aaa; color:white; height:21px; border:1px #666 solid; opacity:0.8; filter:alpha(opacity=80)} .ztree li a.tmpTargetNode_prev {} .ztree li a.tmpTargetNode_next {} .ztree li a input.rename {height:14px; width:80px; padding:0; margin:0; font-size:12px; border:1px #585956 solid; *border:0px} .ztree li span {line-height:21px; margin-right:2px} .ztree li span.button {line-height:0; margin:0; padding: 0; width:21px; height:21px; display: inline-block; vertical-align:middle; border:0 none; cursor: pointer;outline:none; background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; background-image:url("../img/v-tree.png");} .ztree li span.button.chk {width:13px; height:13px; margin:0 2px; cursor: auto} .ztree li span.button.chk.checkbox_false_full {background-position: -5px -5px;} .ztree li span.button.chk.checkbox_false_full_focus {background-position: -5px -26px;} .ztree li span.button.chk.checkbox_false_part {background-position: -5px -48px;} .ztree li span.button.chk.checkbox_false_part_focus {background-position: -5px -68px;} .ztree li span.button.chk.checkbox_false_disable {background-position: -5px -89px;} .ztree li span.button.chk.checkbox_true_full {background-position: -26px -5px;} .ztree li span.button.chk.checkbox_true_full_focus {background-position: -26px -26px;} .ztree li span.button.chk.checkbox_true_part {background-position: -26px -48px;} .ztree li span.button.chk.checkbox_true_part_focus {background-position: -26px -68px;} .ztree li span.button.chk.checkbox_true_disable {background-position: -26px -89px;} .ztree li span.button.chk.radio_false_full {background-position: -47px -5px;} .ztree li span.button.chk.radio_false_full_focus {background-position: -47px -26px;} .ztree li span.button.chk.radio_false_part {background-position: -47px -47px;} .ztree li span.button.chk.radio_false_part_focus {background-position: -47px -68px;} .ztree li span.button.chk.radio_false_disable {background-position: -47px -89px;} .ztree li span.button.chk.radio_true_full {background-position: -68px -5px;} .ztree li span.button.chk.radio_true_full_focus {background-position: -68px -26px;} .ztree li span.button.chk.radio_true_part {background-position: -68px -47px;} .ztree li span.button.chk.radio_true_part_focus {background-position: -68px -68px;} .ztree li span.button.chk.radio_true_disable {background-position: -68px -89px;} .ztree li span.button.switch {width:21px; height:21px} .ztree li span.button.root_open{background-position:-105px -63px} .ztree li span.button.root_close{background-position:-126px -63px} .ztree li span.button.roots_open{background-position: -105px 0;} .ztree li span.button.roots_close{background-position: -126px 0;} .ztree li span.button.center_open{background-position: -105px -21px;} .ztree li span.button.center_close{background-position: -126px -21px;} .ztree li span.button.bottom_open{background-position: -105px -42px;} .ztree li span.button.bottom_close{background-position: -126px -42px;} .ztree li span.button.noline_open{background-position: -105px -84px;} .ztree li span.button.noline_close{background-position: -126px -84px;} .ztree li span.button.root_docu{ background:none;} .ztree li span.button.roots_docu{background-position: -84px 0;} .ztree li span.button.center_docu{background-position: -84px -21px;} .ztree li span.button.bottom_docu{background-position: -84px -42px;} .ztree li span.button.noline_docu{ background:none;} .ztree li span.button.ico_open{margin-right:2px; background-position: -147px -21px; vertical-align:top; *vertical-align:middle} .ztree li span.button.ico_close{margin-right:2px; background-position: -147px 0; vertical-align:top; *vertical-align:middle} .ztree li span.button.ico_docu{margin-right:2px; background-position: -147px -42px; vertical-align:top; *vertical-align:middle} .ztree li span.button.edit {margin-left:2px; margin-right: -1px; background-position: -189px -21px; vertical-align:top; *vertical-align:middle} .ztree li span.button.edit:hover { background-position: -168px -21px; } .ztree li span.button.remove {margin-left:2px; margin-right: -1px; background-position: -189px -42px; vertical-align:top; *vertical-align:middle} .ztree li span.button.remove:hover { background-position: -168px -42px; } .ztree li span.button.add {margin-left:2px; margin-right: -1px; background-position: -189px 0; vertical-align:top; *vertical-align:middle} .ztree li span.button.add:hover { background-position: -168px 0; } .ztree li span.button.ico_loading{margin-right:2px; vertical-align:top; *vertical-align:middle} ul.tmpTargetzTree {background-color:#FFE6B0; opacity:0.8; filter:alpha(opacity=80)} span.tmpzTreeMove_arrow {width:16px; height:21px; display: inline-block; padding:0; margin:2px 0 0 1px; border:0 none; position:absolute; background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; background-position:-168px -84px; background-image:url("../img/v-tree.png"); } ul.ztree.zTreeDragUL {margin:0; padding:0; position:absolute; width:auto; height:auto;overflow:hidden; background-color:#cfcfcf; border:1px #00B83F dotted; opacity:0.8; filter:alpha(opacity=80)} .ztreeMask {z-index:10000; background-color:#cfcfcf; opacity:0.0; filter:alpha(opacity=0); position:absolute}
<template> <div> <ul class="ztree"> <vTree v-for="(node,index) in treeData" :key="index" :checkBoxType="checkBoxType" :allOpen="allOpen" :beforeClick="beforeClick" :checkBox="checkBox" :nodeTrigger="nodeTrigger" :index="index" :tree="node" :first="index===0" :last="treeData.length-1===index" :currentArray="treeData" :parentTree="node.parentTree" :rootData="treeData" :checkBoxCallInit="checkBoxCallInit" :checkBoxCall="checkBoxCall" :clickNode="clickNode" :hiddenLine="hiddenLine" :async="async" :asyncCall="asyncCall" /> </ul> </div> </template> <script> import vTree from './tree-core' export default { components: {vTree}, name: "tree", props: { treeNode: { type: Array, default: function () { return []; }, required: true, }, allOpen: { type: Boolean, default: null, required: false, }, nodeTrigger: { type: Boolean, default: false, required: false, }, checkBox: { type: Boolean, default: false, required: false, }, checkBoxType: { type: Boolean, default: true, required: false, }, beforeClick: { type: Function, default: null }, clickNode: { type: Function, }, asyncCall: { type: Function, }, hiddenLine: { type: Boolean, default: false, required: false, }, async: { type: Boolean, default: false, required: false, }, }, data() { return { treeData: [], line: '', first: true, allOpens: this.allOpen, checkedBoxCallArr: [], } }, methods: { init() { let tempList = JSON.parse(JSON.stringify(this.treeNode)); let initTree = (tree, parent) => { for (let index = 0; index < tree.length; index++) { let m = tree[index]; if (!m.hasOwnProperty("id")) { m.id = m.hasOwnProperty("id") ? m.id : null; } if (!m.hasOwnProperty("open")) { m.open = m.hasOwnProperty("open") ? m.open : false; } if (!m.hasOwnProperty("checked")) { m.checked = m.hasOwnProperty("checked") ? m.checked : false; } if (!m.hasOwnProperty("checkBox")) { m.checkBox = m.hasOwnProperty("checkBox") ? m.checkBox : false; } if (!m.hasOwnProperty("nodeTrigger")) { m.nodeTrigger = m.hasOwnProperty("nodeTrigger") ? m.nodeTrigger : false; } if (!m.hasOwnProperty("checkBoxType")) { m.checkBoxType = this.checkBoxType } if (!m.hasOwnProperty("last")) { m.last = m.hasOwnProperty("last") ? m.last : false; } if (!m.hasOwnProperty("first")) { m.first = m.hasOwnProperty("first") ? m.first : false; } if (!m.hasOwnProperty("active")) { m.active = m.hasOwnProperty("active") ? m.active : false; } if (!m.hasOwnProperty("async")) { m.async = this.async; } if (!m.hasOwnProperty("hiddenLine")) { m.hiddenLine = this.hiddenLine; } if (!m.hasOwnProperty("parentTree")) { m.parentTree = parent ? parent : null; } m.children = m.children || []; if (m.children.length > 0) initTree(m.children, m); } }; initTree(tempList, null); this.treeData = tempList; this.line = 'line'; if (this.first) this.$emit('call', this.treeData); }, changeStatus() { let changeOpen = (data) => { data.forEach(d => { d.open = this.allOpen; if (d.children) changeOpen(d.children); }); }; changeOpen(this.treeData); }, checkBoxCallInit(arr) { arr.forEach(a => { this.checkedBoxCallArr.push(a); }); }, checkBoxCall(arr, isAdd) { if (isAdd) arr.forEach(a => { this.checkedBoxCallArr.push(a); }); else { arr.forEach(a => { if (this.checkBoxCall.length === 0) return; let key = (a.id ? a.id : null) + a.index + a.name; this.checkedBoxCallArr.forEach((ss, index) => { if (((ss.id ? ss.id : null) + ss.index + ss.name) === key) { this.checkedBoxCallArr.splice(index, 1); } }); }); } this.$emit('checkBoxCall', this.checkedBoxCallArr); }, }, created() { this.init(); }, update() { }, mounted() { /*复选框回调*/ this.$emit('checkBoxCall', this.checkedBoxCallArr); }, watch: { allOpen() { this.changeStatus() } } } </script> <style scoped> @import "../../../../static/css/v-tree.css"; </style>
<template> <li> <span v-if="vif()" title="" @click="vShow(tree)" class="button switch" :class="vTreeFirstSpan()"></span> <span v-else title="" class="button switch " :class="classes()"></span> <span v-if="checkBox" @click="selectCheckBox(tree)" class="button chk" :class="tree.checked?'checkbox_true_full':'checkbox_false_full'"></span> <a target="_blank" style="" @click="selectNode" :class="aClass()" :title="tree.name"> <span :title="tree.name" class="button" :class="iconCss()" :style="load()"></span> <span class="node_name">{{tree.name}}</span> </a> <ul :class="line"> <treeCore v-for="(tr,i) in tree.children" v-show="tree.open" :key="i" :checkBoxType="checkBoxType" :allOpen="tr.allOpen" :first="false" :checkBox="checkBox" :nodeTrigger="nodeTrigger" :index="i" :tree="tr" :currentArray="tree.children" :parentTree="tr.parentTree" :rootData="rootData" :clickNode="clickNode" @checkedBoxV="checkedBoxV" :beforeClick="beforeClick" :checkBoxCallInit="checkBoxCallInit" :checkBoxCall="checkBoxCall" :last="tree.children.length-1===i" :hiddenLine="tr.hiddenLine" :async="async" :asyncCall="asyncCall" /> </ul> </li> </template> <script> export default { name: "treeCore", props: { tree: { type: Object, required: true, }, allOpen: { type: Boolean, default: null, required: false, }, nodeTrigger: { type: Boolean, default: false, required: false, }, checkBox: { type: Boolean, default: false, required: false, }, checkBoxType: { type: Boolean, default: true, required: false, }, beforeClick: { type: Function, default: null }, last: { type: Boolean, default: null, required: false, }, first: { type: Boolean, default: true, required: false, }, currentArray: { type: Array, required: true, }, index: { type: Number, required: true, }, rootData: { type: Array, required: true, }, parentTree: { type: Object, required: false, }, checkBoxCallInit: { type: Function, }, checkBoxCall: { type: Function, }, clickNode: { type: Function, }, asyncCall: { type: Function, }, hiddenLine: { type: Boolean, default: false, required: false, }, async: { type: Boolean, default: false, required: false, }, }, data() { return { line: '', currentTree: this.tree, asyncLoading: false, } }, methods: { coreInit() { this.line = this.hiddenLine ? '' : this.currentArray.length - 1 === this.index ? '' : 'line'; if (this.tree.parentTree && this.tree.checked) { /*方案一 Scheme 1*/ let checkedBoxArr = []; checkedBoxArr.push(this.tree); let selectParent = (data) => { if (!data.checked) { data.checked = this.tree.checked; checkedBoxArr.push(data); } if (data.parentTree) { selectParent(data.parentTree); } else { this.checkBoxCallInit(checkedBoxArr); } }; selectParent(this.currentTree); /*方案二 Scheme 2*/ //this.$emit('checkedBoxV') } }, checkedBoxV() { this.tree.checked = true; this.$emit('checkedBoxV') }, pNode(tree) { return tree.open; }, vShow(tree) { /*需要有异步加载 need add async loading*/ /*默认异步加载给他按钮 当加载后才能判别时候有子节点 */ if (this.async && !tree.open && tree.children.length === 0) { this.asyncCall.call(this, tree, this.asyncBack); this.asyncLoading = true; } tree.open = !tree.open; }, asyncBack(requestDataArr) { if (typeof requestDataArr) this.addNode(requestDataArr); this.asyncLoading = false; }, selectNode() { let isClick = this.beforeClick.call(this, this.tree); if (isClick) { //清除其它 let pro = null; let clearStyle = (data) => { for (let i = 0; i < data.length; i++) { let d = data[i]; if (d.active) { pro = d; d.active = !d.active; } else if (d.children) { clearStyle(d.children); } } }; clearStyle(this.rootData); this.tree.active = true; if (this.nodeTrigger) { this.tree.open = !this.tree.open; } this.clickNode.call(this, this.tree, pro); } }, addNode(arr) { try { arr.forEach(a => { this.tree.children.push({ id: a.id ? a.id : null, name: a.name, open: a.open ? a.open : false, checked: a.checked ? a.checked : false, checkBox: a.checkBox ? a.checkBox : false, nodeTrigger: a.nodeTrigger ? a.nodeTrigger : this.nodeTrigger, checkBoxType: this.checkBoxType, last: false, first: false, active: false, async: this.async, hiddenLine: this.hiddenLine, parentTree: this.tree, children: [], }); }); } catch (e) { console.error('The asynchronous callback parameter must be an array,异步回调参数必须是数组'); } }, selectCheckBox(tree) { tree.checked = !tree.checked; let checkedBoxArr = []; checkedBoxArr.push(tree); if (this.checkBoxType) { /*级联*/ let changeChecked = (data) => { data.forEach(d => { checkedBoxArr.push(d); d.checked = tree.checked; if (d.children) changeChecked(d.children); }); }; changeChecked(tree.children); let checkChildren = (data) => { for (let i = 0; i < data.length; i++) { if (data[i].checked) return true; } }; let selectParent = (data) => { if (data.children.length > 1) { const childExistsThis = []; data.children.forEach((m, index) => { if (index !== this.index) childExistsThis.push(m); }); if (childExistsThis && data.checked && checkChildren(childExistsThis)) return; } checkedBoxArr.push(data); data.checked = tree.checked; if (data.parentTree) selectParent(data.parentTree); }; if (this.parentTree) selectParent(this.parentTree); } this.checkBoxCall(checkedBoxArr, tree.checked); } }, created() { this.coreInit(); }, computed: { vif() { return function () { return this.async ? true : this.tree.children.length > 0; } }, vTreeFirstSpan() { return function () { return this.hiddenLine ? this.tree.open ? 'noline_open treenode_switch' : 'noline_close treenode_switch' : this.currentArray.length - 1 === this.index ? this.tree.open ? 'bottom_open' : 'bottom_close' : this.tree.open ? 'roots_open' : 'roots_close'; } }, classes() { return function () { return this.hiddenLine ? 'noline_docu' : this.first ? 'roots_docu' : this.currentArray.length - 1 === this.index ? 'bottom_docu' : 'center_docu' } }, iconCss() { return function () { return this.tree.children.length > 0 ? this.tree.open ? 'ico_open' : 'ico_close' : 'ico_docu'; } }, load() { return function () { return this.asyncLoading ? 'background:url(../../static/img/loading.gif) 0 0 no-repeat' : '' } }, aClass() { return function () { return this.tree.active ? 'curSelectedNode' : ''; } } }, watch: { tree: { handler(oldV, newV) { if (newV.checked) this.tree.checked = newV.checked; }, deep: true }, } } </script> <style scoped> @import "../../../../static/css/v-tree.css"; </style>
<template> <div style="height: auto"> <div class="main"> <ul> <li> <Tree :treeNode="treeNode" :clickNode="clickNode" :beforeClick="beforeClick" :hiddenLine="hiddenLine" :async="async" @call='callAsync' :asyncCall="asyncCall" :nodeTrigger="nodeTrigger" /> </li> </ul> </div> </div> </template> <script> import Tree from "./tree"; export default { components: {Tree}, data() { return { treeNode: [], nodeTrigger: false, // 所有节点 trees: [], hiddenLine: false, async: true, } }, methods: { beforeClick(node) { //可操作内部 return true; }, /*回调初始化后的数据 以后修改tree实现对节点的操作即可*/ call(data) { console.log('data', data); // this.trees = data; }, callAsync(data) { //this.trees = data; }, /*点击节点信息 上个点击节点信息*/ clickNode(data, oldData) { /*if(data.children){ data.children.push({ id: (new Date()).getTime(), name:'新增节点', children:[] }); }else{ }*/ // console.log(data); //data.open=true; }, /*异步回调函数 data 当前节点数据 call 回调函数*/ asyncCall(data, call) { setTimeout(function () { let hm = '' + (new Date()).getTime(); let addNode = [ {id: hm, name: "children node" + hm.substr(hm.length - 4, hm.length)}, ]; console.log(data.id) // call(addNode); call([]) }, 800); } }, mounted() { // this.allOpen = true; }, created() { this.treeNode = [ { id: "1", name: "父节点22 - 折叠", open: true, // 文件夹open = true/false // 文件:不显示图像 // 添加右键弹出操作 children: [ {id: "1-1", name: "叶子节点221",open: true}, {id: "1-2", name: "叶子节点222",open: true}, {id: "1-3", name: "叶子节点223",open: true}, {id: "1-4", name: "叶子节点224",open: true} ] }, { id: "2", name: "父节点23 - 折叠", children: [ {id: "2-1", name: "叶子节点231"}, {id: "2-2", name: "叶子节点232"}, {id: "2-3", name: "叶子节点233"}, {id: "2-4", name: "叶子节点234"} ] }, { open: true, id: "3", name: "父节点24 - 折叠", children: [ { id: "2-1-1", name: "叶子节点232", open: true, children: [ {id: "2-1-3", name: "叶子节点2313"}, {id: "2-2-3", name: "叶子节点2323"}, {id: "2-3-3", name: "叶子节点2333"}, {id: "2-4-3", name: "叶子节点2343"} ] }, ] }, ]; } } </script> <style scoped> .main ul li { list-style: none; float: left; width: 25%; } </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。