效果图其他个人定义组件
使用案例
<template>
<div class="staff">
<v-sidebar @change="sideChang()" :dataBar="side"></v-sidebar>
</div>
</template>
<script>
import vSidebar from '@/components/common/v-sidebar'
export default {
components:{vSidebar,vtable},
name: "staff",
methods:{
sideChang(val){
console.log(val)
}
},
data() {
return {
side: [
{
value: "1",
label: "测试1",
children: [
{
value: "1-1",
label: "测试1-1",
children: [
{
value: "1-1-1",
label: "测试1-1-1"
},
{
value: "1-1-2",
label: "测试1-1-2"
}
]
},
{
value: "1-2",
label: "测试1-2"
}
]
}
]
};
},
};
</script>
<style lang="less" scoped>
.container_main{
align-items: flex-start;
padding: 0 20px;
.title{
margin: 0 20px 10px;
padding: 10px 0;
border-bottom:2px solid #ff7c35;
display: inline-block;
}
.left{
width: 240px;
height: 100%;
.side{
background: #f5f5f5;
height: 100%;
}
.title{
margin: 0 0 10px;
}
}
.right{
width: calc(100% - 240px);
.right_tip{
align-items: flex-start;
}
}
}
</style>
v-sidebar.vue
<script>
export default {
name: 'sidebar',
props: {
dataBar: {
type: Array,
default: () => {
return []
}
}
},
data() {
return {
sideBar: [],
padding: -13,
defaultIcon: 'el-icon-plus',
activeIcon: 'el-icon-minus',
isActive: '',
level: 0
}
},
watch: {
dataBar: {
deep: true,
handler: function() {
this.sideBar = this.setArr(this.dataBar, -13)
this.sideBar.forEach((item) => {
item.isActive = true
})
}
},
'isActive':function(val){
this.change(val)
}
},
created() {
this.sideBar = this.setArr(this.dataBar, -13)
this.sideBar.forEach((item) => {
item.isActive = true
})
},
render() {
return <div class="side">{this.setSide(this.sideBar)}</div>
},
methods: {
//change事件
change(val){
this.$emit('change',val)
},
//侧边栏生成
setSide(arr) {
return arr.map((item) => {
if (item.children) {
return (
<div class="side-group">
<p
onClick={() => {
this.sideClick(item)
}}
class={
item.isActive ? 'side-item' : 'side-item'
}
style={'padding-left:' + item.pad + 'px'}
>
<i class={item.icon}></i>
<span>{item.label}</span>
</p>
<div class="side-group" v-show={item.isActive}>
{this.setSide(item.children)}
</div>
</div>
)
} else {
return (
<p
onClick={() => {
this.itemClick(item)
}}
style={'padding-left:' + item.pad + 'px'}
class={
item.value == this.isActive
? 'side-item side-item-active'
: 'side-item'
}
>
{item.label}
</p>
)
}
})
},
//侧边栏数据处理
setArr(arr, ind) {
return arr.map((item) => {
if (item.children && item.children.length > 0) {
return {
...item,
icon: this.defaultIcon,
isActive: false,
pad: ind + 23,
children: this.setArr(item.children, ind + 23)
}
} else {
return {
...item,
icon: this.defaultIcon,
isActive: false,
pad: ind + 23
}
}
})
},
//激活选项
itemClick(val) {
if (val.value == this.isActive) {
this.isActive = ''
} else {
this.isActive = val.value
}
this.$emit('change', val)
},
//菜单展开
sideClick(val) {
val.icon = val.isActive ? this.defaultIcon : this.activeIcon
val.isActive = !val.isActive
this.$emit('change', val)
}
}
}
</script>
<style lang="less" scoped>
.side {
border: 1px solid #dcd2d2;
border-bottom: none;
}
.side-item {
cursor: pointer;
padding: 10px 0;
border-bottom: 1px solid #dcd2d2;
i {
margin-right: 10px;
}
}
.side-item:hover {
background: #84b3e4;
color: #fff;
}
.side-group {
background: #f5f5f5;
}
.side-item-active {
background: #409eff;
color: #fff;
}
</style>