需求: 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. Django服务器布置(Ubuntu+uwsgi+nginx+Django)

    一.安装Python apt install python3 二.安装pip apt install python3-pip 三.创建目录 创建虚拟服务目录 mkdir -p /data/env 创建 ...

  2. .NET Core项目自动化测试和代码覆盖率审查

    这篇文章给大家分享一下,如何配置.NET Core项目自动化测试和代码覆盖率审查. 基本知识,请参考这里: https://docs.microsoft.com/en-us/dotnet/core/t ...

  3. HEXO添加置顶功能

    使用库:参考 http://wangwlj.com/2018/01/09/blog_pin_post/ 目前已经有修改后支持置顶的仓库,可以直接用以下命令安装.(cmd 到博客根目录,nmp运行) $ ...

  4. codeforces 11B Jumping Jack

    Jack is working on his jumping skills recently. Currently he's located at point zero of the number l ...

  5. Leetcode(3)-无重复字符的最长子串

    给定一个字符串,找出不含有重复字符的最长子串的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3. 给定 &q ...

  6. nodejs非安装版配置(windows)

    nodejs官网下载地址: https://nodejs.org/en/download/ 解压到本地并配置环境变量 在环境变量path中新增 D:\develop\node 查看是否配置成功 至此n ...

  7. js Nullish Coalescing Operator

    js Nullish Coalescing Operator 空值合并 const n = null ?? 'default string'; console.log(n); // "def ...

  8. 如何使用 js 实现一个 Promise.all 方法 PromiseAll

    如何使用 js 实现一个 Promise.all 方法 PromiseAll Promise.all PromiseAll https://developer.mozilla.org/en-US/do ...

  9. React & Didact

    React & Didact A DIY guide to build your own React https://github.com/pomber/didact https://gith ...

  10. scroll tabs

    scroll tabs https://github.com/NervJS/taro-ui/blob/dev/src/components/tabs/index.tsx https://github. ...