48 lines
1.3 KiB
Vue
48 lines
1.3 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
import { useAuthStore } from '@/stores/auth'
|
|
import { DataAnalysis, List, Monitor } from '@element-plus/icons-vue'
|
|
|
|
type MenuItem = {
|
|
name: string
|
|
label: string
|
|
icon?: any
|
|
roles?: string[]
|
|
}
|
|
|
|
const auth = useAuthStore()
|
|
const route = useRoute()
|
|
const router = useRouter()
|
|
|
|
const items = computed<MenuItem[]>(() => [
|
|
{ name: 'dashboard', label: '仪表盘', icon: Monitor },
|
|
{ name: 'orders', label: '订单管理', icon: List },
|
|
{ name: 'dashboard', label: '统计分析', icon: DataAnalysis, roles: ['manager', 'admin'] },
|
|
])
|
|
|
|
const visibleItems = computed(() => {
|
|
const r = auth.role
|
|
return items.value.filter((it) => !it.roles || (r && it.roles.includes(r)))
|
|
})
|
|
|
|
const active = computed(() => {
|
|
const n = route.name
|
|
return typeof n === 'string' ? n : ''
|
|
})
|
|
|
|
const onSelect = async (name: string) => {
|
|
await router.push({ name })
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<el-menu :default-active="active" class="border-0" @select="onSelect">
|
|
<el-menu-item v-for="it in visibleItems" :key="it.name" :index="it.name">
|
|
<el-icon v-if="it.icon"><component :is="it.icon" /></el-icon>
|
|
<span>{{ it.label }}</span>
|
|
</el-menu-item>
|
|
</el-menu>
|
|
</template>
|
|
|