步骤:
定义模板(做循环遍历处理):
<template>
<div class="container">
<el-card v-for="(item,index) in routeList" :key="index" class="routeList-box">
<!-- <el-collapse v-model="activeNames">
<el-collapse-item :title="item.title" :name="index"> -->
<el-tree
ref="tree"
class="el-tree"
show-checkbox
node-key="id"
:indent="0"
:data="item.list"
:props="defaultProps"
:highlight-current="true"
:default-expand-all="true"
:render-content="renderContent"
@node-expand="handleExpand"
/>
<!--:indent="0"为相邻级节点间的水平缩进,单位为像素,如果要加指示线需设置为0,否则缩进会很大-->
<!-- </el-collapse-item>
</el-collapse> -->
</el-card>
</div>
</template>
tree的参数说明请参考官方文档el-tree
定义模板数据:
data() {
return {
routeList: [
{
// title: '授权管理后台',
list: [
{
id: 1,
label: '工程管理', //一级控件
children: [
{
id: 2,
label: '物料管理', //二级控件
children: [
{
id: 4,
label: '列表查看', //三级控件
// children: [
// {
// id: 7,
// label: '页面查看权限' //四级控件
// },
// {
// id: 8,
// label: '编辑'
// }
// ]
},
{
id: 5,
label: '查询',
// children: [
// {
// id: 9,
// label: '次数分布child1'
// },
// {
// id: 10,
// label: '次数分布child2'
// }
// ]
}
]
},
{
id: 3,
label: '工艺流程管理',
children: [
{
id: 6,
label: '列表查看',
// children: [
// {
// id: 7,
// label: '页面查看权限'
// }
// ]
},
{
id: 7,
label: '查询',
// children: [
// {
// id: 7,
// label: '页面查看权限'
// }
// ]
}
]
}
]
},
{
id: 111,
label: '销售管理',
children: [
{
id: 112,
label: '订单管理',
children: [
{
id: 113,
label: '列表查看'
},
{
id: 114,
label: '查询'
},
{
id: 114,
label: '重置'
},
{
id: 114,
label: '复选框'
},
{
id: 114,
label: '新增订单'
},
{
id: 114,
label: '导出'
},
{
id: 114,
label: '打印'
},
{
id: 114,
label: '操作'
},
{
id: 114,
label: '订单详情'
},
{
id: 114,
label: '编辑'
},
{
id: 114,
label: '作废'
},
{
id: 114,
label: '出库'
},
{
id: 114,
label: '结束'
}
]
}
]
}
]
}
],
defaultProps: {
children: 'children',
label: 'label'
}
}
}
js部分:
mounted() {
this.changeCss() //默认调用此方法将子节点渲染为横向排列
},
methods: {
handleExpand() { // 节点被展开时触发的事件
// 因为该函数执行在renderContent函数之前,所以得加this.$nextTick()
this.$nextTick(() => {
this.changeCss()
})
},
renderContent(h, { node, data, store }) { // 树节点的内容区的渲染 Function
let classname = ''
// 由于项目中有三级菜单也有四级级菜单,就要在此做出判断
if (node.level === 4) {
classname = 'foo'
}
if (node.level === 3 && node.childNodes.length === 0) {
classname = 'foo'
}
return h(
'p',
{
class: classname
},
node.label
)
},
changeCss() { //将子节点横向排列方法
var levelName = document.getElementsByClassName('foo') // levelname是上面的最底层节点的名字
for (var i = 0; i < levelName.length; i++) {
// cssFloat 兼容 ie6-8 styleFloat 兼容ie9及标准浏览器
levelName[i].parentNode.style.cssFloat = 'left' // 最底层的节点,包括多选框和名字都让他左浮动
levelName[i].parentNode.style.styleFloat = 'left'
levelName[i].parentNode.onmouseover = function() {
this.style.backgroundColor = '#fff'
}
}
}
}
指示线样式部分:
<style scoped lang="scss">
// 树样式
.el-tree{
::v-deep .el-tree-node{
position: relative;
padding-left: 16px; // 缩进量
}
::v-deep .el-tree-node__children{
padding-left: 16px; // 缩进量
}
// 竖线
::v-deep .el-tree-node::before{
content:"";
height: 100%;
width: 1px;
position: absolute;
left: -3px;
top: -26px;
border-width: 1px;
border-left: 1px dashed #ccc;
}
// 当前层最后⼀个节点的竖线⾼度固定
::v-deep .el-tree-node:last-child::before{
height: 38px; // 可以⾃⼰调节到合适数值
}
// 横线
::v-deep .el-tree-node::after{
content:"";
width: 24px;
height: 20px;
position: absolute;
left: -3px;
top: 12px;
border-width: 1px;
border-top: 1px dashed #ccc;
}
// 去掉最顶层的虚线,放最下⾯样式才不会被上⾯的覆盖了
& > ::v-deep .el-tree-node::after{
border-top: none;
}
& > ::v-deep .el-tree-node::before{
border-left: none;
}
// 展开关闭的icon
::v-deep .el-tree-node__expand-icon{
font-size: 16px;
// 叶⼦节点(⽆⼦节点)
::v-deep &.is-leaf{
color: transparent;
// display: none; // 也可以去掉
}
}
}
</style>
实际效果: