Commit 944fdeba authored by Administrator's avatar Administrator
Browse files

managed menus dynamically in constant

/src/components/constans/menuItems.js
parent bcee74f8
......@@ -7,18 +7,96 @@
>
<v-list-item title="Welcome to Students App" subtitle="powered by vuetify"></v-list-item>
<v-divider></v-divider>
<v-list>
<v-list-item link title="Home" @click="$router.push('/')"></v-list-item>
<v-list-item link title="Profile" @click="$router.push('/profile')"></v-list-item>
<v-list v-model:opened="opened">
<template v-for="item in filteredMenu" :key="item.path || item.name">
<!-- 分组(有 children):点击父项仅用于展开,不路由 -->
<v-list-group
v-if="item.children && item.children.length"
:value="item.path"
:prepend-icon="item.mdiIcon"
>
<template #activator="{ props }">
<v-list-item v-bind="props">
<v-list-item-title class="text-body-1">{{ item.name }}</v-list-item-title>
</v-list-item>
</template>
<v-list-item
v-for="child in item.children"
:key="child.path || child.name"
:prepend-icon="child.mdiIcon"
:to="child.hasRouter ? child.path : undefined"
:ripple="child.hasRouter"
:disabled="!child.hasRouter"
nav
>
<v-list-item-title class="text-body-1">{{ child.name }}</v-list-item-title>
</v-list-item>
</v-list-group>
<!-- 非分组(无 children) -->
<v-list-item
v-else
:prepend-icon="item.mdiIcon"
:to="item.hasRouter ? item.path : undefined"
:ripple="item.hasRouter"
:disabled="false"
@click="!item.hasRouter ? noop() : undefined"
nav>
<v-list-item-title class="text-body-1">{{ item.name }}</v-list-item-title>
</v-list-item>
</template>
</v-list>
</v-navigation-drawer>
</template>
<script setup>
const props = defineProps({
import { ref, computed, onMounted, watch } from 'vue'
import { useRoute } from 'vue-router'
import { GLOBAL_MENU_ITEMS } from './constants/menuItems'
defineProps({
modelValue: Boolean
})
const emit = defineEmits(['update:modelValue'])
const route = useRoute()
// 预留权限/可见性过滤钩子(当前直接返回所有项)
const filteredMenu = computed(() => {
// TODO: 可根据角色/权限在此过滤 GLOBAL_MENU_ITEMS
return GLOBAL_MENU_ITEMS
})
// 控制 v-list-group 展开
const opened = ref([])
// 初始化和根据当前路由自动展开相关分组
const ensureOpenedByRoute = (currentPath) => {
const groupsToOpen = []
for (const item of filteredMenu.value) {
if (item && item.children && item.children.length) {
const hit = item.children.some(child => !!child.path && currentPath.startsWith(child.path))
if (hit && item.path) {
groupsToOpen.push(item.path)
}
}
}
opened.value = groupsToOpen
}
onMounted(() => {
ensureOpenedByRoute(route.path)
})
watch(() => route.path, (p) => {
ensureOpenedByRoute(p)
})
// 无操作占位(用于非路由点击)
const noop = () => {}
</script>
<style scoped>
......
<template>
<v-footer app color="primary" dark :elevation="2">
<v-col class="text-center white--text">
&copy; 2025 Student App
&copy; 2025 Student Management App
</v-col>
</v-footer>
</template>
......
export const GLOBAL_MENU_ITEMS = [
{
name: 'Home',
path: '/',
mdiIcon: 'mdi-home',
hasRouter: true
},
{
name: 'Profile',
path: '/profile',
mdiIcon: 'mdi-account-card',
hasRouter: true
},
{
name: 'Master Data',
path: '/master-data',
mdiIcon: 'mdi-database-outline',
hasRouter: false,
children: [
{
name: 'Students',
path: '/students',
mdiIcon: 'mdi-account-school',
hasRouter: true
},
{
name: 'Subjects',
path: '/subjects',
mdiIcon: 'mdi-book-open-blank-variant-outline',
hasRouter: true
}
]
},
// 可以继续添加更多菜单项
];
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment