first commit
This commit is contained in:
124
resources/admin/layout/components/Menu/index.vue
Normal file
124
resources/admin/layout/components/Menu/index.vue
Normal file
@@ -0,0 +1,124 @@
|
||||
<script lang="ts">
|
||||
import { h, defineComponent, VNode } from 'vue'
|
||||
import { usePermissionsStore } from '/admin/stores/modules/user/permissions'
|
||||
import MenuItem from './item.vue'
|
||||
import menus from './menus.vue'
|
||||
import { useUserStore } from '/admin/stores/modules/user'
|
||||
import { Menu } from '/admin/types/Menu'
|
||||
|
||||
/**
|
||||
* 递归渲染 Menu 节点
|
||||
*/
|
||||
function getVNodes(menus: Menu[] | undefined, _subMenuClass: string | undefined): VNode[] {
|
||||
const vnodes: VNode[] = []
|
||||
menus?.forEach(menu => {
|
||||
if (!menu.meta?.hidden) {
|
||||
let vnode: VNode
|
||||
const len = menu.children?.length
|
||||
if (len) {
|
||||
vnode = h(
|
||||
MenuItem,
|
||||
{
|
||||
subMenuClass: _subMenuClass,
|
||||
menu,
|
||||
},
|
||||
{
|
||||
default: () => getVNodes(menu.children, 'children-menu'),
|
||||
},
|
||||
)
|
||||
} else {
|
||||
vnode = h(MenuItem, {
|
||||
subMenuClass: _subMenuClass,
|
||||
menu,
|
||||
})
|
||||
}
|
||||
vnodes.push(vnode)
|
||||
}
|
||||
})
|
||||
|
||||
return vnodes
|
||||
}
|
||||
|
||||
/**
|
||||
* filter menus
|
||||
*
|
||||
* @param menus
|
||||
*/
|
||||
function filterMenus(menus: Menu[] | undefined): Menu[] {
|
||||
const newMenus: Menu[] = []
|
||||
|
||||
menus?.forEach(m => {
|
||||
if (m.meta?.hidden) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (isHasOnlyChild(m) && m.children?.length) {
|
||||
newMenus.push(
|
||||
Object.assign({
|
||||
path: m.children[0].path,
|
||||
meta: m.children[0].meta,
|
||||
name: m.name,
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
newMenus.push(m)
|
||||
}
|
||||
})
|
||||
|
||||
return newMenus
|
||||
}
|
||||
|
||||
/**
|
||||
* is has only child
|
||||
*
|
||||
* @param menu
|
||||
*/
|
||||
function isHasOnlyChild(menu: Menu): boolean {
|
||||
if (menu.children === undefined) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (menu.children.length > 1 || !menu.children.length) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (menu.children[0].children?.length) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
subMenuClass: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
menuClass: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
setup(props, ctx) {
|
||||
const permissionsStore = usePermissionsStore()
|
||||
const userStore = useUserStore()
|
||||
|
||||
// 后端的 permissions 返回 undefined,则认为该后端无权限系统
|
||||
const permissions = userStore.getPermissions === undefined ? [] : userStore.getPermissions
|
||||
const vnodes = getVNodes(filterMenus(permissionsStore.getMenusFrom(permissions)), props.subMenuClass)
|
||||
|
||||
return () => {
|
||||
return h(
|
||||
menus,
|
||||
{
|
||||
class: 'border-none side-menu ' + props.menuClass,
|
||||
},
|
||||
{
|
||||
default: () => vnodes,
|
||||
},
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
Reference in New Issue
Block a user