需求: vue实现仿zTree折叠树,此文章仅作为记录文档。

实现:

<template>
<div class="line-tree">
<div v-for="(item, index) in treeData" :key="index" class="single-content" :class="treeLine ? getSecond(item) : ''">
<span></span>
<p class="parent-node">
<!-- treeLine 是否显示连接线 -->
<span v-if="treeLine">
<span class="line-7" v-if="level !== 0 && (item.children && item.children.length)"></span>
<span class="line-25" v-if="level !== 0 && (!item.children || !item.children.length)"></span>
<span v-if="item.last" class="line-10-last"></span>
</span> <span v-if="item.children && item.children.length && item.name" class="arrow-icon" @click="changeState(item)">
<img src="../../../../static/images/jurisdiction-add.png" v-if="!item.expand" alt="+" class="expand-icon">
<img src="../../../../static/images/jurisdiction-cut.png" v-else alt="-" class="expand-icon">
</span>
<span v-else>
<i style="display: inline-block; height: 14px; width: 16px; position: relative; top: 2px;"></i>
</span>
<span v-if="keyTree == 'role'">
<span class="city" :class="{'active-name' : treeActive === item.id}" @click="item.children.length === 0 ? skipCost(item) : parentClick(item)">{{item.name}}</span>
</span>
<span v-else>
<span class="city" :class="{'active-name' : treeActive === item.id}" @click="(item.children.length === 0 || item.deep === 1) ? skipCost(item) : parentClick(item)">{{item.name}}</span>
</span>
</p> <div v-if="item.children && item.children.length && item.expand" class="sub-content" :class="treeLine ? cancelBor(item) : ''">
<permission-base-tree @skipCost="skipCost" :currentDep="currentDep" :level="level + 1" :treeData="item.children" :keyTree="keyTree"></permission-base-tree>
</div>
</div>
</div>
</template>
<script>
import { mapGetters, mapMutations } from "vuex";
export default {
name: 'permission-base-tree',
data() {
return {}
},
props: {
treeData: {
type: Array,
default: () => []
},
level: {
type: Number,
default: () => 0
},
currentDep: {
type: Number,
default: () => 0
},
keyTree: {
type: String,
default: () => ""
},
treeLine: {
type: Boolean,
default: () => false
}
},
computed: {
...mapGetters(["treeActive"])
},
watch: {
treeData: {
handler(newVal, oldVal) {
if (newVal) {
this.treeData = newVal;
}
},
deep:true
},
},
created() {
},
methods: {
...mapMutations({
setActive: 'SET_treeActive'
}),
skipCost(item) {
this.setActive(item.id);
this.$emit('skipCost', item);
},
parentClick(item) {
this.setActive(item.id);
item.expand = !item.expand;
}, /**
* 改变生效状态
*/
changeEffect(item, sub) {
this.$emit('changeEffect', [item, sub]);
},
/**
* 添加
*/
add(item) {
console.log('item', item);
this.$emit('add', item);
},
/**
* 编辑
*/
edit(item, sub) {
this.$emit('edit', [item, sub]);
},
/**
* 删除
*/
deleteWarning(item, sub) {
this.$emit('deleteWarning', [item, sub]);
},
changeSelect(item, index){
item.select = !item.select;
if (item.select) { // 子类全选
if (item.children && item.children.length) {
// 子类变为选中状态
this.transferTrue(item.children, true);
}
console.log('select',[true, item.levelList]);
this.$emit('changeParent', [true, item.levelList]);
} else { // 取消全选
if (item.children && item.children.length) {
this.transferTrue(item.children, false);
}
this.$emit('changeParent', [false, item.levelList]);
}
},
changeParent(val) {
if (val[0]) { // 子类为true
let flag = true;
let arr = val[1].slice(0, val[1].length - 1);
let idx = arr[arr.length - 1];
for (let i = 0; i < this.treeData[idx].children.length; i++) {
if (!this.treeData[idx].children[i].select) {
flag = false;
break;
}
}
if (flag) {
this.treeData[idx].select = true;
} else {
this.treeData[idx].select = false;
}
this.$emit('changeParent', [true, this.treeData[idx].levelList])
} else {
let arr = val[1].slice(0, val[1].length - 1);
let idx = arr[arr.length - 1];
this.treeData[idx].select = false;
this.$emit('changeParent', [false, this.treeData[idx].levelList],val[2]);
}
},
cancelBor(item) {
if (!item.last) {
return 'add-second';
}
},
getSecond(item) {
if (!item.last) {
return 'add-second';
}
}, getMargin(item) {
let currentLevel = item.level;
if (item.children && item.children.length) {
return {
marginRight: (this.currentDep - item.level - 1) * 18 + 'px'
}
}
},
transferTrue(arr, flag) {
arr.forEach((item, index) => {
item.select = flag;
if (item.children && item.children.length) {
this.transferTrue(item.children, flag);
}
})
},
changeState(item) {
item.expand = !item.expand;
}
}
}
</script>
<style lang="less" scoped>
.line-tree {
font-size: #000;
.single-content {
position: relative;
left: -11px;
padding-left: 11px;
}
.single-troditional {
display: inline-block;
height: 24px;
line-height: 24px;
background: #B1D6FF;
margin-right: 10px;
padding: 0 5px;
color: #000;
border-radius: 3px;
}
.common-img {
display: inline-block;
margin-left: 5px;
}
.common-img:hover {
cursor: pointer;
}
.add-continal {
color: #0847A9;
margin-right: 15px;
}
.add-continal:hover {
cursor: pointer;
}
.add-second {
border-left: 1px dashed #FFF;
}
.line-15 {
position: absolute;
left: -10px;
top: 15px;
display: inline-block;
width: 1px;
height: 13px;
border-left: 1px dashed #FFF;
}
.line-10 {
position: absolute;
left: -10px;
top: 0;
display: inline-block;
width: 1px;
height: 15px;
border-left: 1px dashed #FFF;
}
.line-10-last {
position: absolute;
left: -11px;
top: 0;
display: inline-block;
width: 1px;
height: 15px;
border-left: 1px dashed #FFF;
}
.line-7 {
position: absolute;
left: -10px;
top: 15px;
display: inline-block;
width: 7px;
height: 1px;
border-bottom: 1px dashed #FFF;
}
.line-25 {
position: absolute;
left: -10px;
top: 15px;
display: inline-block;
width: 25px;
height: 1px;
border-bottom: 1px dashed #FFF;
}
.sub-content {
margin-left: 7px;
padding-left: 11px;
}
.add-border {
border-left: 1px dashed #FFF;
}
.parent-node {
height: 30px;
vertical-align: middle;
position: relative;
white-space: nowrap;
}
img {
vertical-align: middle;
}
.file-icon {
display: inline-block;
width: auto;
height: 14px;
}
.arrow:hover {
cursor: pointer;
}
.select-icon {
display: inline-block;
width: 15px;
height: 15px;
}
.last-content {
padding-left: 30px;
}
.select-box:hover {
cursor: pointer;
}
.city {
font-size: 14px;
color: #000;
display: inline-block;
height: 30px;
line-height: 30px;
}
.active-name {
color: #0847A9;
font-weight: bold;
text-decoration: underline;
}
.city:hover {
cursor: pointer;
}
.expand-icon {
display: inline-block;
height: 14px;
width: auto;
}
.expand-icon:hover {
cursor: pointer;
}
.init-line {
position: absolute;
left: 7px;
top: -3px;
display: inline-block;
width: 0;
height: 8px;
box-sizing: border-box;
border-left: 1px dashed #FFF;
}
.outer {
position: absolute;
left: 7px;
top: 2px;
display: inline-block;
width: 14px;
height: 20px;
box-sizing: border-box;
border-left: 1px dashed #FFF;
.inner {
display: inline-block;
width: 10px;
height: 0;
box-sizing: border-box;
border-bottom: 1px dashed #FFF;
position: relative;
top: 0px;
}
} .outer-sub {
position: absolute;
left: 7px;
display: inline-block;
width: 14px;
height: 13px;
top: 2px;
box-sizing: border-box;
border-left: 1px dashed #FFF;
.inner-sub {
display: inline-block;
width: 10px;
height: 0;
box-sizing: border-box;
border-bottom: 1px dashed #FFF;
position: relative;
top: 0px;
}
}
}
</style>

vue 仿zTree折叠树的更多相关文章

  1. web页面显示折叠树菜单笔记

    zTree -- jQuery 树插件 http://pan.baidu.com/s/1skwh94h

  2. 帆软报表(finereport) 折叠树

    在进行展现数据时,希望模板的数据是可以动态折叠的,即点击数据前面的加号才展开对应下面的数据,可通过树节点按钮实现折叠树效果 实现思路: 1.这里建立一个内置数据集 添加数据 设置模板样式,添加颜色和对 ...

  3. vue-resource使用 (vue仿百度搜索)

    1.this.$http.get()方法2.this.$http.post()方法3.this.$http.jsonp()方法 (vue仿百度搜索) 在输入框中输入a, 然后在百度f12 ==> ...

  4. vue 仿今日头条

    vue 仿今日头条 为了增加移动端项目的经验,近一周通过 vue 仿写今日头条,以下就项目实现过程中遇到的问题以及解决方法给出总结,有什么不正确的地方,恳请大家批评指正^ _ ^!,代码仓库地址为 g ...

  5. 【ztree】zTree取消树节点选中的背景色

    点击树节点的时候是ztree给树加了个class:    curSelectedNode 所以最简单的清除树节点的背景色的方法是移除其有背景色的class: $(".curSelectedN ...

  6. Vue 实现展开折叠效果

    Vue 实现展开折叠效果 效果参见:https://segmentfault.com/q/1010000011359250/a-1020000011360185 上述链接中,大佬给除了解决方法,再次进 ...

  7. Nuxt|Vue仿探探/陌陌卡片式滑动|vue仿Tinder拖拽翻牌效果

    探探/Tinder是一个很火的陌生人社交App,趁着国庆假期闲暇时间倒腾了个Nuxt.js项目,项目中有个模块模仿探探滑动切换界面效果.支持左右拖拽滑动like和no like及滑动回弹效果. 一览效 ...

  8. zTree -- jQuery 树插件 使用方法与例子

    简介 zTree 是一个依靠 jQuery 实现的多功能 "树插件". 网址:http://www.ztree.me/v3/main.php#_zTreeInfo 上面的网址里有z ...

  9. zTree静态树与动态树的用法——(七)

    0.[简介] zTree 是利用 JQuery 的核心代码,实现一套能完成大部分常用功能的 Tree 插件 兼容 IE.FireFox.Chrome 等浏览器 在一个页面内可同时生成多个 Tree 实 ...

随机推荐

  1. codeforces 1037E-Trips 【构造】

    题目:戳这里 题意:n个点,每天早上会在这n个点中加一条边,每天晚上最大的子图满足子图中每个点都有k条或以上的边. 解题思路:看了官方题解,先把所有的点都连上,再从最后一天往前减边,用set维护最大的 ...

  2. 2019牛客多校第一场I Points Division(DP)题解

    题意: n个点,分成两组A,B,如果点i在A中,那么贡献值\(a_i\),反之为\(b_i\). 现要求任意\(i \in A,j \in B\)不存在 \(x_i >= x_j\) 且 \(y ...

  3. bash copy multi files

    bash copy multi files # copy one file $ cp file1.js /var/www/html # copy multi files ??? no space $ ...

  4. JavaScript string repeat methods All In One

    JavaScript string repeat methods All In One There are many ways in the ES-Next ways repeat ES2015 / ...

  5. CSS clip-path in action

    CSS clip-path in action <!DOCTYPE html> <html lang="en"> <head> <meta ...

  6. js script all in one

    js script all in one 你不知道的 js secret https://html.spec.whatwg.org/multipage/scripting.html https://h ...

  7. element ui 停止维护了

    ️‍♂️ element ui 停止维护了 最近看到有人说 element ui 已经停止维护了,还有点不相信; 不过到 github 验证一下,好像是真的呀 4 个月,没有任何更新了 https:/ ...

  8. JavaScript Best Practice

    JavaScript Best Practice Clean, maintainable, execute code

  9. Axios & POST & application/x-www-form-urlencoded

    Axios & POST & application/x-www-form-urlencoded application/x-www-form-urlencoded https://g ...

  10. py conda 换源

    安装软件 $ conda install wxpython 如果出现http错误,安装OpenSSL $ conda config --add channels https://mirrors.tun ...