效果图
1、通过slot-scope插槽来自定义样式
:icon-class="'1'"
这里主要是为了把icon给冲突掉不显示 随便赋个值就可以
<el-tree
:data="data"
node-key="id"
:default-expanded-keys="active"
ref="selectTree"
:icon-class="'1'"
:indent="29"
:highlight-current="true"
:props="defaultProps">
<span class="my-custom" slot-scope="{node,data}">
<span v-if="node.parent.expanded" class="heng"></span>
<span v-if="node.expanded" :style="'bottom:-'+ (node.childNodes.length * 26 - 5.1) +'px;'+'height:' + (node.childNodes.length * 26 - 4) + 'px'" class="shu"></span>
<span class="zi">
<!-- node.expanded -->
<i v-if='node.childNodes.length != 0 ' @click="handleIconClick(node,data)" :class="['iconfont',,node.expanded ? 'icon-jian' :'icon-jia','tree-icon']"></i>
{{node.label}}
</span>
</span>
</el-tree>
2、把所有的内容全部折叠
for(var i=0;i<this.$refs.selectTree.store._getAllNodes().length;i++){
this.$refs.selectTree.store._getAllNodes()[i].expanded = false;
}
3、设置要展开的内容
主要是通过这个el-tree中的default-expanded-keys这属性来设置要默认展开的内容
url:http://localhost:8080/#/tree?active=7
:default-expanded-keys="active"
this.active = this.$route.query.active ? this.$route.query.active.split(',') : [];
4、设置选中样式
主要是通过setCurrentKey
方法来实现
因为一次只能激活一个所有就不能传数组了
元素在被激活时会有 is-current
class名
.app{
.is-current>.el-tree-node__content{
animation:mymove 0.66s infinite alternate;
-webkit-animation:mymove 0.66s infinite alternate;
}
@keyframes mymove
{
from {background:#f0f7ff;}
to {background:rgb(197,216,255);}
}
@-webkit-keyframes mymove /*Safari and Chrome*/
{
from {background:#f0f7ff;}
to {background:rgb(197,216,255);}
}
this.$refs.selectTree.setCurrentKey(this.active[0])
5、样式问题通过node中属性来判断当前元素是否处于展开状态或者被展开状态来判断是否要显示线
所有代码
<template>
<div class="app">
<el-tree
:data="data"
node-key="id"
:default-expanded-keys="active"
ref="selectTree"
:icon-class="'1'"
:indent="29"
:highlight-current="true"
:props="defaultProps">
<span class="my-custom" slot-scope="{node,data}">
<span v-if="node.parent.expanded" class="heng"></span>
<span v-if="node.expanded" :style="'bottom:-'+ (node.childNodes.length * 26 - 5.1) +'px;'+'height:' + (node.childNodes.length * 26 - 4) + 'px'" class="shu"></span>
<span class="zi">
<!-- node.expanded -->
<i v-if='node.childNodes.length != 0 ' @click="handleIconClick(node,data)" :class="['iconfont',,node.expanded ? 'icon-jian' :'icon-jia','tree-icon']"></i>
{{node.label}}
</span>
</span>
</el-tree>
</div>
</template>
<script>
export default {
name:"tree",
data() {
return {
active:[],
data: [{
id: 1,
label: '一级 1',
icon:'iconfont icon-jia',
children: [{
id: 4,
label: '二级 1-1',
icon:'iconfont icon-jia',
children: [{
id: 9,
label: '三级 1-1-1',
icon:'iconfont icon-jia',
}, {
id: 10,
label: '三级 1-1-2',
icon:'iconfont icon-jia',
}]
}]
}, {
id: 2,
icon:'iconfont icon-jia',
label: '一级 2',
children: [{
id: 5,
icon:'iconfont icon-jia',
label: '二级 2-1'
}, {
id: 6,
icon:'iconfont icon-jia',
label: '二级 2-2'
}]
}, {
id: 3,
icon:'iconfont icon-jia',
label: '一级 3',
children: [{
id: '课堂',
icon:'iconfont icon-jia',
label: '二级 3-1'
}, {
id: 8,
icon:'iconfont icon-jia',
label: '二级 3-2'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
};
},
methods:{
handleIconClick(node){
console.log(node,node.expanded);
}
},
watch:{
$route:function(){
// if(this.$route.query.active == ''){
// this.$route.query.active = '0'
// }
console.log(this.$route.query)
// if(this.$route.query.active){
for(var i=0;i<this.$refs.selectTree.store._getAllNodes().length;i++){
this.$refs.selectTree.store._getAllNodes()[i].expanded = false;
}
// }
this.active = this.$route.query.active ? this.$route.query.active.split(',') : [];
this.$refs.selectTree.setCurrentKey(this.active[0])
}
},
computed:{
// active:function(){
// console.log(this.$refs.selectTree)
// // for(var i=0;i<this.$refs.selectTree.store._getAllNodes().length;i++){
// // // this.$refs.selectTree
// // // .store._getAllNodes()[i].expanded = false;
// // }
// if(this.$route.query.active){
// return this.$route.query.active.split(',')
// }else{
// return []
// }
// }
},
mounted(){
// console.log(this.$route.query.active);
this.active = this.$route.query.active ? this.$route.query.active.split(',') : [];
this.$refs.selectTree.setCurrentKey(this.active[0])
}
}
</script>
<style lang="less" >
.app{
.my-custom{
position: relative;
}
.heng{
position: absolute;
left: -16px;
width: 16px;
top:(50%-0.9px);
height:1.8px;
background:#cacaca
}
@font-face {
font-family: 'iconfont'; /* project id 1877686 */
src: url('//at.alicdn.com/t/font_1877686_wtt40d3lrf.eot');
src: url('//at.alicdn.com/t/font_1877686_wtt40d3lrf.eot?#iefix') format('embedded-opentype'),
url('//at.alicdn.com/t/font_1877686_wtt40d3lrf.woff2') format('woff2'),
url('//at.alicdn.com/t/font_1877686_wtt40d3lrf.woff') format('woff'),
url('//at.alicdn.com/t/font_1877686_wtt40d3lrf.ttf') format('truetype'),
url('//at.alicdn.com/t/font_1877686_wtt40d3lrf.svg#iconfont') format('svg');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 0.6em;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color:#fff;
background: #cacaca;
border-radius: 50%;
padding: 0.2em;
// line-height: 1.2em;
font-weight: bold;
position: relative;
}
.icon-jia:before {
content: "\e615";
}
.icon-jian:before {
content: "\e60c";
}
.icon-jian:after{
// content: '';
// // border: 1px solid #cacaca;
// position: absolute;
// bottom: -1.69em;
// height:1.6em;
// width: 1.8px;
// left: 0.8em;
// background: #cacaca;
}
.shu{
position: absolute;
width: 1.8px;
left: 0.8em;
height: 0;
background: #cacaca;
}
// .el-tree-node__expand-icon{
// display: none;
// }
// .el-icon-caret-right::after{
// content: "\e615";
// }
// .el-icon-caret-right{
// }
.zi{
border: 1px solid #ccc;
border-radius: 0.3em;
padding: 0.12em 0.24em;
position: relative;
}
.el-tree-node__content{
margin: 0.1em 0;
}
.is-current>.el-tree-node__content{
animation:mymove 0.66s infinite alternate;
-webkit-animation:mymove 0.66s infinite alternate;
}
@keyframes mymove
{
from {background:#f0f7ff;}
to {background:rgb(197,216,255);}
}
@-webkit-keyframes mymove /*Safari and Chrome*/
{
from {background:#f0f7ff;}
to {background:rgb(197,216,255);}
}
}
</style>