Vue嵌套路由的各種用法詳解
一、Vue 嵌套路由基礎(chǔ)
1. 定義嵌套路由
在 Vue Router 中,嵌套路由可以通過在路由配置中定義 children 屬性來實現(xiàn)。例如,以下是一個簡單的嵌套路由配置:
import { createRouter, createWebHistory } from 'vue-router'; const routes = [ { path: '/', component: () => import('./views/Home.vue'), }, { path: '/dashboard', component: () => import('./views/Dashboard.vue'), children: [ { path: 'profile', component: () => import('./views/Profile.vue'), }, { path: 'settings', component: () => import('./views/Settings.vue'), }, ], }, ]; const router = createRouter({ history: createWebHistory(), routes, }); export default router;
在這個例子中,/dashboard 是父路由,/dashboard/profile 和 /dashboard/settings 是子路由。
2. 使用嵌套路由
在父組件中,可以通過 來渲染子路由的組件:
<template> <el-menu :default-active="$route.path" router> <el-menu-item index="/home">首頁</el-menu-item> <el-menu-item index="/users">用戶管理</el-menu-item> <el-sub-menu index="/dashboard"> <template #title>儀表盤</template> <el-menu-item index="/dashboard/profile">個人資料</el-menu-item> <el-menu-item index="/dashboard/settings">設(shè)置</el-menu-item> </el-sub-menu> </el-menu> </template>
二、Element Plus Menu 基礎(chǔ)用法
Element Plus 的 Menu 組件支持多種用法,包括水平菜單、垂直菜單、折疊菜單等。以下是一些基本用法:
1. 垂直菜單
<template> <el-menu :default-active="$route.path" router> <el-menu-item index="/home">首頁</el-menu-item> <el-menu-item index="/users">用戶管理</el-menu-item> <el-sub-menu index="/dashboard"> <template #title>儀表盤</template> <el-menu-item index="/dashboard/profile">個人資料</el-menu-item> <el-menu-item index="/dashboard/settings">設(shè)置</el-menu-item> </el-sub-menu> </el-menu> </template>
在這個例子中,el-menu 的 router 屬性用于激活當前路由對應(yīng)的菜單項。
2. 水平菜單
水平菜單可以通過設(shè)置 mode=“horizontal” 來實現(xiàn):
<template> <el-menu mode="horizontal" :default-active="$route.path" router> <el-menu-item index="/home">首頁</el-menu-item> <el-menu-item index="/users">用戶管理</el-menu-item> <el-sub-menu index="/dashboard"> <template #title>儀表盤</template> <el-menu-item index="/dashboard/profile">個人資料</el-menu-item> <el-menu-item index="/dashboard/settings">設(shè)置</el-menu-item> </el-sub-menu> </el-menu> </template>
三、Vue 嵌套路由與 Element Plus Menu 的結(jié)合
1. 動態(tài)菜單
可以通過動態(tài)綁定數(shù)據(jù)來生成菜單項。例如,從后端獲取菜單數(shù)據(jù)并渲染:
<template> <el-menu :default-active="$route.path" router> <template v-for="item in menuData" :key="item.index"> <el-menu-item v-if="!item.children" :index="item.index"> {{ item.label }} </el-menu-item> <el-sub-menu v-else :index="item.index"> <template #title>{{ item.label }}</template> <el-menu-item v-for="child in item.children" :key="child.index" :index="child.index"> {{ child.label }} </el-menu-item> </el-sub-menu> </template> </el-menu> </template> <script setup> import { ref } from 'vue'; const menuData = ref([ { index: '/home', label: '首頁' }, { index: '/users', label: '用戶管理' }, { index: '/dashboard', label: '儀表盤', children: [ { index: '/dashboard/profile', label: '個人資料' }, { index: '/dashboard/settings', label: '設(shè)置' }, ], }, ]); </script>
在這個例子中,menuData 是一個動態(tài)生成的菜單數(shù)據(jù)數(shù)組。
2. 路由模式
當與 Vue Router 結(jié)合使用時,可以通過 router 屬性激活當前路由對應(yīng)的菜單項。例如:
<template> <el-menu :default-active="$route.path" router> <el-menu-item index="/home">首頁</el-menu-item> <el-menu-item index="/users">用戶管理</el-menu-item> <el-sub-menu index="/dashboard"> <template #title>儀表盤</template> <el-menu-item index="/dashboard/profile">個人資料</el-menu-item> <el-menu-item index="/dashboard/settings">設(shè)置</el-menu-item> </el-sub-menu> </el-menu> </template>
在這個例子中,el-menu 的 router 屬性會根據(jù)當前路由路徑($route.path)自動激活對應(yīng)的菜單項。
3. 菜單事件處理
Element Plus 的 Menu 組件提供了多種事件,例如 select、open 和 close??梢酝ㄟ^這些事件來處理菜單的交互邏輯。例如:
<template> <el-menu :default-active="$route.path" router @select="handleSelect"> <el-menu-item index="/home">首頁</el-menu-item> <el-menu-item index="/users">用戶管理</el-menu-item> <el-sub-menu index="/dashboard"> <template #title>儀表盤</template> <el-menu-item index="/dashboard/profile">個人資料</el-menu-item> <el-menu-item index="/dashboard/settings">設(shè)置</el-menu-item> </el-sub-menu> </el-menu> </template> <script setup> import { ref } from 'vue'; const handleSelect = (index) => { console.log(`Selected menu: ${index}`); }; </script>
在這個例子中,handleSelect 方法會在菜單項被選中時觸發(fā)。
四、高級用法
1. 權(quán)限控制
在實際應(yīng)用中,通常需要根據(jù)用戶的權(quán)限動態(tài)顯示菜單項??梢酝ㄟ^在路由配置中添加權(quán)限屬性,并在菜單渲染時進行過濾。例如:
const routes = [ { path: '/home', component: () => import('./views/Home.vue'), meta: { requiresAuth: false }, }, { path: '/users', component: () => import('./views/Users.vue'), meta: { requiresAuth: true }, }, { path: '/dashboard', component: () => import('./views/Dashboard.vue'), children: [ { path: 'profile', component: () => import('./views/Profile.vue'), meta: { requiresAuth: true }, }, { path: 'settings', component: () => import('./views/Settings.vue'), meta: { requiresAuth: true }, }, ], }, ];
然后在菜單渲染時,根據(jù)用戶權(quán)限過濾菜單項:
<template> <el-menu :default-active="$route.path" router> <template v-for="item in filteredMenuData" :key="item.index"> <el-menu-item v-if="!item.children" :index="item.index"> {{ item.label }} </el-menu-item> <el-sub-menu v-else :index="item.index"> <template #title>{{ item.label }}</template> <el-menu-item v-for="child in item.children" :key="child.index" :index="child.index"> {{ child.label }} </el-menu-item> </el-sub-menu> </template> </el-menu> </template> <script setup> import { ref, computed } from 'vue'; import { useStore } from 'vuex'; const store = useStore(); const menuData = ref([ { index: '/home', label: '首頁', meta: { requiresAuth: false } }, { index: '/users', label: '用戶管理', meta: { requiresAuth: true } }, { index: '/dashboard', label: '儀表盤', children: [ { index: '/dashboard/profile', label: '個人資料', meta: { requiresAuth: true } }, { index: '/dashboard/settings', label: '設(shè)置', meta: { requiresAuth: true } }, ], }, ]); const filteredMenuData = computed(() => { return menuData.value.filter((item) => { if (!item.children) { return !item.meta.requiresAuth || store.state.isAuthenticated; } else { item.children = item.children.filter((child) => { return !child.meta.requiresAuth || store.state.isAuthenticated; }); return item.children.length > 0; } }); }); </script>
在這個例子中,filteredMenuData 是一個計算屬性,根據(jù)用戶的認證狀態(tài)(store.state.isAuthenticated)動態(tài)過濾菜單項。
2. 菜單的動態(tài)加載
在某些情況下,菜單數(shù)據(jù)可能需要從后端動態(tài)加載??梢酝ㄟ^異步請求獲取菜單數(shù)據(jù),并在獲取完成后渲染菜單。例如:
<template> <el-menu :default-active="$route.path" router v-if="menuData.length > 0"> <template v-for="item in menuData" :key="item.index"> <el-menu-item v-if="!item.children" :index="item.index"> {{ item.label }} </el-menu-item> <el-sub-menu v-else :index="item.index"> <template #title>{{ item.label }}</template> <el-menu-item v-for="child in item.children" :key="child.index" :index="child.index"> {{ child.label }} </el-menu-item> </el-sub-menu> </template> </el-menu> </template> <script setup> import { ref, onMounted } from 'vue'; import axios from 'axios'; const menuData = ref([]); onMounted(async () => { try { const response = await axios.get('/api/menu'); menuData.value = response.data; } catch (error) { console.error('Failed to load menu data:', error); } }); </script>
在這個例子中,onMounted 生命周期鉤子用于在組件掛載時從后端加載菜單數(shù)據(jù)。
3. 菜單的國際化
在國際化應(yīng)用中,菜單項的標題可能需要根據(jù)用戶的語言偏好動態(tài)顯示??梢酝ㄟ^ Vue I18n 來實現(xiàn)菜單的國際化。例如:
<template> <el-menu :default-active="$route.path" router> <template v-for="item in menuData" :key="item.index"> <el-menu-item v-if="!item.children" :index="item.index"> {{ $t(item.label) }} </el-menu-item> <el-sub-menu v-else :index="item.index"> <template #title>{{ $t(item.label) }}</template> <el-menu-item v-for="child in item.children" :key="child.index" :index="child.index"> {{ $t(child.label) }} </el-menu-item> </el-sub-menu> </template> </el-menu> </template> <script setup> import { ref } from 'vue'; import { useI18n } from 'vue-i18n'; const { t } = useI18n(); const menuData = ref([ { index: '/home', label: 'menu.home' }, { index: '/users', label: 'menu.users' }, { index: '/dashboard', label: 'menu.dashboard', children: [ { index: '/dashboard/profile', label: 'menu.profile' }, { index: '/dashboard/settings', label: 'menu.settings' }, ], }, ]); </script> <i18n> { "en": { "menu": { "home": "Home", "users": "Users", "dashboard": "Dashboard", "profile": "Profile", "settings": "Settings" } }, "zh": { "menu": { "home": "首頁", "users": "用戶管理", "dashboard": "儀表盤", "profile": "個人資料", "settings": "設(shè)置" } } } </i18n>
在這個例子中,$t 方法用于動態(tài)翻譯菜單項的標題。
4. 菜單的折疊與展開
Element Plus 的 Menu 組件支持折疊和展開功能??梢酝ㄟ^設(shè)置 collapse 屬性來控制菜單的折疊狀態(tài)。例如:
<template> <div> <el-button @click="toggleCollapse">切換菜單</el-button> <el-menu :default-active="$route.path" router :collapse="isCollapsed"> <el-menu-item index="/home">首頁</el-menu-item> <el-menu-item index="/users">用戶管理</el-menu-item> <el-sub-menu index="/dashboard"> <template #title>儀表盤</template> <el-menu-item index="/dashboard/profile">個人資料</el-menu-item> <el-menu-item index="/dashboard/settings">設(shè)置</el-menu-item> </el-sub-menu> </el-menu> </div> </template> <script setup> import { ref } from 'vue'; const isCollapsed = ref(false); const toggleCollapse = () => { isCollapsed.value = !isCollapsed.value; }; </script>
在這個例子中,isCollapsed 是一個響應(yīng)式變量,用于控制菜單的折疊狀態(tài)。點擊按鈕時,toggleCollapse 方法會切換菜單的折疊狀態(tài)。
5. 菜單的自定義樣式
可以通過自定義 CSS 來調(diào)整菜單的樣式。例如:
.el-menu { background-color: #f5f7fa; border-right: none; } .el-menu-item { color: #333; } .el-menu-item.is-active { background-color: #409eff; color: #fff; } .el-sub-menu__title { color: #333; } .el-sub-menu__title:hover { background-color: #e6f7ff; }
在這個例子中,自定義了菜單的背景顏色、字體顏色和激活狀態(tài)的樣式。
五、完整示例
以下是一個完整的示例,結(jié)合了嵌套路由、動態(tài)菜單、權(quán)限控制、國際化和折疊功能:
- 路由配置
import { createRouter, createWebHistory } from 'vue-router'; const routes = [ { path: '/', component: () => import('./views/Home.vue'), meta: { requiresAuth: false }, }, { path: '/users', component: () => import('./views/Users.vue'), meta: { requiresAuth: true }, }, { path: '/dashboard', component: () => import('./views/Dashboard.vue'), children: [ { path: 'profile', component: () => import('./views/Profile.vue'), meta: { requiresAuth: true }, }, { path: 'settings', component: () => import('./views/Settings.vue'), meta: { requiresAuth: true }, }, ], meta: { requiresAuth: true }, }, ]; const router = createRouter({ history: createWebHistory(), routes, }); export default router;
- 菜單組件
<template> <div> <el-button @click="toggleCollapse">切換菜單</el-button> <el-menu :default-active="$route.path" router :collapse="isCollapsed"> <template v-for="item in filteredMenuData" :key="item.index"> <el-menu-item v-if="!item.children" :index="item.index"> {{ $t(item.label) }} </el-menu-item> <el-sub-menu v-else :index="item.index"> <template #title>{{ $t(item.label) }}</template> <el-menu-item v-for="child in item.children" :key="child.index" :index="child.index"> {{ $t(child.label) }} </el-menu-item> </el-sub-menu> </template> </el-menu> </div> </template> <script setup> import { ref, computed } from 'vue'; import { useStore } from 'vuex'; import { useI18n } from 'vue-i18n'; const { t } = useI18n(); const store = useStore(); const menuData = ref([ { index: '/home', label: 'menu.home', meta: { requiresAuth: false } }, { index: '/users', label: 'menu.users', meta: { requiresAuth: true } }, { index: '/dashboard', label: 'menu.dashboard', children: [ { index: '/dashboard/profile', label: 'menu.profile', meta: { requiresAuth: true } }, { index: '/dashboard/settings', label: 'menu.settings', meta: { requiresAuth: true } }, ], meta: { requiresAuth: true }, }, ]); const isCollapsed = ref(false); const toggleCollapse = () => { isCollapsed.value = !isCollapsed.value; }; const filteredMenuData = computed(() => { return menuData.value.filter((item) => { if (!item.children) { return !item.meta.requiresAuth || store.state.isAuthenticated; } else { item.children = item.children.filter((child) => { return !child.meta.requiresAuth || store.state.isAuthenticated; }); return item.children.length > 0; } }); }); </script> <i18n> { "en": { "menu": { "home": "Home", "users": "Users", "dashboard": "Dashboard", "profile": "Profile", "settings": "Settings" } }, "zh": { "menu": { "home": "首頁", "users": "用戶管理", "dashboard": "儀表盤", "profile": "個人資料", "settings": "設(shè)置" } } } </i18n>
- 樣式
.el-menu { background-color: #f5f7fa; border-right: none; } .el-menu-item { color: #333; } .el-menu-item.is-active { background-color: #409eff; color: #fff; } .el-sub-menu__title { color: #333; } .el-sub-menu__title:hover { background-color: #e6f7ff; }
六、總結(jié)
通過結(jié)合 Vue 嵌套路由和 Element Plus 的 Menu 組件,可以實現(xiàn)功能豐富且靈活的導(dǎo)航菜單。本文介紹了從基礎(chǔ)用法到高級功能的多種場景,包括動態(tài)菜單、權(quán)限控制、國際化、折疊功能和自定義樣式。這些功能可以根據(jù)實際需求靈活組合,以滿足復(fù)雜應(yīng)用的需求。
以上就是Vue嵌套路由的各種用法詳解的詳細內(nèi)容,更多關(guān)于Vue嵌套路由用法的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
npm install -g @vue/cli安裝vue腳手架報錯問題(一般都能解決)
這篇文章主要介紹了npm install -g @vue/cli安裝vue腳手架報錯問題(一般都能解決),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10vue代理請求之Request?failed?with?status?code?404問題及解決
這篇文章主要介紹了vue代理請求之Request?failed?with?status?code?404問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07Vue 兩個字段聯(lián)合校驗之修改密碼功能的實現(xiàn)
本文以校驗兩次密碼的一致性應(yīng)用,給出兩個可變屬性值的字段之間的聯(lián)合校驗的典型解決方案,通過實例代碼給大家介紹Vue 兩個字段聯(lián)合校驗之修改密碼功能的實現(xiàn),需要的朋友一起看看吧2021-07-07