需求: 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. 蓝桥杯-摔手机问题【dp】

    非常详细的题解:戳这里 例题:poj-3783 Balls Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 115 ...

  2. codeforces 14D(搜索+求树的直径模板)

    D. Two Paths time limit per test 2 seconds memory limit per test 64 megabytes input standard input o ...

  3. C++ part3

    函数和const references: C++中const用于函数重载 有些情况可以重载,有些不行,具体看↑. 隐式类型转换 references: nowcoder 对于内置类型,低精度的变量给高 ...

  4. springboot demo(二)web开发demo

    如入门般建立项目,引入依赖: <dependencies> <dependency> <groupId>org.springframework.boot</g ...

  5. POJ 3415 Common Substrings(后缀数组 + 单调栈)题解

    题意: 给两个串\(A.B\),问你长度\(>=k\)的有几对公共子串 思路: 先想一个朴素算法: 把\(B\)接在\(A\)后面,然后去跑后缀数组,得到\(height\)数组,那么直接\(r ...

  6. 杭电多校HDU 6601 Keen On Everything But Triangle(主席树)题解

    题意: 有\(n\)根长度不一的棍子,q次询问,求\([L,R]\)区间的棍子所能组成的周长最长的三角形.棍长\(\in [1, 1e9]\),n\(\in [1, 1e5]\). 思路: 由于不构成 ...

  7. 洛谷p1725 露琪诺 单调队列优化的DP

    #include <iostream> #include <cstdio> #include <cstring> using namespace std; int ...

  8. Vue Login Form Component

    Vue Login Form Component Account Login <template> <div> <slot></slot> <el ...

  9. SQL Tutorials & MySQL & SQL Server

    SQL Tutorials SQL MySQL https://www.mysql.com/ $ mysql --version # mysql Ver 8.0.21 for osx10.15 on ...

  10. React Learning Paths

    React Learning Paths React Expert React in Action The assessment may cover: Components Events and Bi ...