NGToolsAdmin/components/uni-nav-menu/uni-nav-menu.vue
2024-09-13 16:39:31 +08:00

210 lines
4.5 KiB
Vue

<template>
<view class="uni-nav-menu" :style="{'background-color':backgroundColor}">
<slot>
<uni-menu-sidebar :data="data"></uni-menu-sidebar>
</slot>
</view>
</template>
<script>
export default {
name: 'uniNavMenu',
props: {
data: {
type: Array,
default () {
return []
}
},
// 模式 可选值 horizontal / vertical
mode: {
type: String,
default: 'vertical'
},
// 是否水平折叠收起菜单(仅在 mode 为 vertical 时可用)
collapse: {
type: Boolean,
default: false
},
// 菜单的背景色
backgroundColor: {
type: String,
default: '#fff'
},
// 菜单的文字颜色
textColor: {
type: String,
default: '#303133'
},
// 当前激活菜单的文字颜色
activeTextColor: {
type: String,
default: '#42B983'
},
// 当前激活菜单的背景色
activeBackgroundColor: {
type: String,
default: 'inherit'
},
// 如果 index 为 Object ,需要指定选中字段的名称
activeKey: {
type: String,
default: 'id'
},
// 当前激活菜单的 index
active: {
type: String,
default: ''
},
// 当前打开的 sub-menu 的 index 的数组
defaultOpeneds: {
type: Array,
default () {
return []
}
},
// 是否只保持一个子菜单的展开
uniqueOpened: {
type: Boolean,
default: false
},
// TODO 子菜单打开的触发方式(只在 mode 为 horizontal 时有效) ,可选值 hover / click
menuTrigger: {
type: String,
default: 'hover'
},
router: {
type: Boolean,
default: false
},
// 是否开启折叠动画
collapseTransition: {
type: Boolean,
default: true
}
},
data() {
return {
activeIndex: this.active
};
},
watch: {
active(newVal) {
this.activeIndex=newVal
},
activeIndex(newVal, oldVal) {
if (this.itemChildrens.length > 0) {
let isActive = false
for(let i = 0 ; i < this.itemChildrens.length ;i++){
const item = this.itemChildrens[i]
isActive = this.isActive(item)
if(isActive) break
}
if(!isActive){
this.closeAll()
}
}
}
},
created() {
this.itemChildrens = []
this.subChildrens = []
// this.activeIndex = this.active
},
methods: {
// menu 菜单激活回调
select(key, keyPath) {
this.$emit('select', key, keyPath)
},
// sub-menu 展开的回调
open(key, keyPath) {
this.$emit('open', key, keyPath)
},
// sub-menu 收起的回调
close(key, keyPath) {
this.$emit('close', key, keyPath)
},
// 判断当前选中,只有初始值会使用
isActive(subItem) {
let active = ''
let isActive = false
if(typeof(subItem.index) === 'object'){
active = subItem.index[this.activeKey] || ''
}else{
active = subItem.index
}
if (subItem.index && this.activeIndex === active) {
isActive = true
subItem.$subMenu.forEach((item, index) => {
if (!item.disabled && !subItem.disabled ) {
subItem.indexPath.push(item.index)
item.isOpen = true
}
})
if(!subItem.active){
subItem.onClickItem('init')
}
}
return isActive
},
// 打开关闭 sunMenu
selectMenu(subMenu){
// const subMenu = this.$menuParent
this.subChildrens.forEach((item,index)=>{
if(item === subMenu){
subMenu.isOpen = !subMenu.isOpen
subMenu.indexPath.push(subMenu.index)
}else{
if(item.isOpen && this.uniqueOpened) item.isOpen = false
}
})
subMenu.$subMenu.forEach((sub,idx)=>{
sub.isOpen = true
subMenu.indexPath.unshift(sub.index)
})
if(subMenu.isOpen){
this.open(subMenu.indexPath[subMenu.indexPath.length-1],subMenu.indexPath)
}else{
this.close(subMenu.indexPath[subMenu.indexPath.length-1],subMenu.indexPath)
}
subMenu.indexPath = []
},
// 关闭其他选中
closeOtherActive(itemMenu) {
// let parents = this.$menuParent
itemMenu.indexPath = []
itemMenu.$subMenu.forEach((item) => {
if (!item.disabled) {
itemMenu.indexPath.push(item.index)
}
})
this.itemChildrens.map((item) => {
if (item.active) {
item.active = false
}
return item
})
},
// 关闭所有
closeAll() {
this.subChildrens.forEach((item) => {
if (item.isOpen) {
item.isOpen = false
}
})
}
}
}
</script>
<style lang="scss">
.uni-nav-menu {
width: 240px;
// min-height: 500px;
background-color: #FFFFFF;
font-size: 14px;
}
</style>