最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue3動態(tài)路由+菜單欄的實現(xiàn)示例

 更新時間:2024年04月02日 08:46:02   作者:湯達人  
在后臺管理系統(tǒng),可以根據(jù)登錄用戶的不同返回不同路由,頁面也會根據(jù)這些路由生成對應(yīng)的菜單,本文主要介紹了vue3動態(tài)路由+菜單欄的實現(xiàn)示例,感興趣的可以了解一下

動態(tài)路由

這里用vue3和vite來實現(xiàn)動態(tài)路由,點擊這里查看效果 源碼

使用場景

在后臺管理系統(tǒng),可以根據(jù)登錄用戶的不同返回不同路由,頁面也會根據(jù)這些路由生成對應(yīng)的菜單。這樣通過服務(wù)器就能控制一個用戶可以訪問的內(nèi)容了。
比如管理員可以看到服務(wù)器日志,可以進行系統(tǒng)設(shè)置,普通用戶就訪問不了這些頁面。

步驟

定義基礎(chǔ)路由表
有一些路由不需要登錄也能訪問的,比如login和404頁面,這些路由要提前在寫好并加入到router中。
編寫路由組件
所有的路由組件都要提前寫好放到/views目錄下
添加路由
定義addRoute()方法,在登錄后獲取服務(wù)器路由通過這個方法添加路由
生成菜單
路由的meta字段可以添加一些菜單相關(guān)的信息,比如菜單名、icon、排序之類的。遍歷路由列表,根據(jù)meta的信息就能生成對應(yīng)的菜單了

代碼

服務(wù)器路由數(shù)據(jù)

這里模擬服務(wù)器返回的數(shù)據(jù),為了方便只寫了一條路由,看源碼有更多示例。
meta的數(shù)據(jù)是自己定的,一定要跟后端對接好。

[  
    {  
        path: '/user',  
        component: 'DEFAULT_LAYOUT',  
        meta: {menuName: '用戶', order: 1},  
        children: [  
            {  
                path: 'info',  
                name: 'userInfo',  
                component: 'user/info',  
                meta: {menuName: '個人中心'}  
            }  
        ]  
    }  
]  

注意

  • 只支持二級路由,也就是子路由下不能再有子路由
  • 每個一級路由至少有一個子路由,即使你只想展示一個菜單。因為父路由需要顯示布局組件,子路由才是真正顯示內(nèi)容的地方。
  • component: 'DEFAULT_LAYOUT'表示這個路由要使用的布局組件,需要提前定義好。
  • meta: {menuName: '用戶', order: 1}menuName表示這個菜單的名稱,order表示菜單的排序,還可以添加其他內(nèi)容,比如
  • 只有一個子路由不想生成二級菜單,就可以設(shè)置single: true
  • 子路由的name,必須設(shè)置這個字段,而且整個路由中不能重復(fù),點擊一個菜單時需要用它來導航
  • 子路由的component表示路由組件的位置,需要提前在/views目錄下把所有路由組件都寫好。比如這里的user/info
  • 實際會導入import('@/views/user/info.vue')。注意:路徑之間必須用/隔開
  • meta: {menuName: '個人中心'}子路由必須定義menuName,因為子路由會生成用戶可以點擊的菜單,沒有名稱的話就不會顯示了

添加路由

假設(shè)現(xiàn)在登錄成功,開始調(diào)用addRoute()方法添加路由,這個方法根據(jù)情況放在自己需要的地方,這里為了演示都放在一起了。

// /components/layout.vue  
import { ref } from 'vue'  
import { useRouter } from 'vue-router'  
// 這個布局組件需要自己提前定義好  
import DEFAULT_LAYOUT from '@/components/layout.vue'  
  
const server_route = ref([])  
  
const addRoute = async () => {  
    // 如果本地沒有路由信息,就從服務(wù)器獲取  
    if (!server_route.value.length) {  
        // 這里模擬從服務(wù)器獲取數(shù)據(jù),實際需要從后端獲取數(shù)據(jù)  
        const { default: routes = [] } = await import('@/router/server_route')  
        server_route.value = routes  
    }  

    // 把路由表的component字段轉(zhuǎn)成真實的路由  
    server_route.value.map((_route) => {  
        if (_route.component === 'DEFAULT_LAYOUT') {  
            _route.component = DEFAULT_LAYOUT  
        }  
        const children = _route.children  
        // 根據(jù)字符串動態(tài)導入路由組件  
        if (Array.isArray(children) && children?.length > 0) {  
            children.map((childRoute) => {  
                const path = childRoute.component.split('/')  
                if (path.length === 1) {  
                    childRoute.component = () => import(`@/views/${path}.vue`)  
                } else {  
                    childRoute.component = () => import(`@/views/${path[0]}/${path[1]}.vue`)  
                }  
            })  
        }  
    })  
  
    // 排序  
    server_route.value.sort((a, b) => (a?.meta?.order ?? 0) - (b?.meta?.order ?? 0))  

    // 循環(huán)添加路由  
    server_route.value.map((route) => router.addRoute(route))  
}  

從服務(wù)器獲取到的數(shù)據(jù)會保存到server_route里面,實際開發(fā)應(yīng)該保存到本地localStorage,否則刷新所有路由消失。
獲取到數(shù)據(jù)還不能用,因為component字段還是字符串,要轉(zhuǎn)成懶加載的形式導入組件才行。

// 把路由表的component字段轉(zhuǎn)成真實的路由  
server_route.value.map((_route) => {  
    if (_route.component === 'DEFAULT_LAYOUT') {  
        // 設(shè)置布局組件,可以為項目設(shè)置多個布局,服務(wù)器只需要修改這里,前端就能顯示多種布局了  
        _route.component = DEFAULT_LAYOUT  
    }  
    const children = _route.children  
    // 根據(jù)字符串動態(tài)導入路由組件  
    if (Array.isArray(children) && children?.length > 0) {  
        children.map((childRoute) => {  
        const path = childRoute.component.split('/')  
        // 用vite提供的動態(tài)導入功能,根據(jù)字符串從views目錄下導入組件  
        // 參考:https://cn.vitejs.dev/guide/features.html#dynamic-import  
        if (path.length === 1) {  
            // 如果是單個vue文件  
            childRoute.component = () => import(`@/views/${path[0]}.vue`)  
        } else {  
            // 否則就是一個目錄  
            childRoute.component = () => import(`@/views/${path[0]}/${path[1]}.vue`)  
        }  
        })  
    }  
}) 

因為父組件的布局組件比較少,一般不用做懶加載全部導入進來,根據(jù)字符串選擇對應(yīng)的布局就行了。

子組件需要動態(tài)的導入。vite提供了根據(jù)變量動態(tài)導入模塊的方法。

如果component: 'user/info'

  • 先const path = childRoute.component.split('/')拆分一下路徑,這時候path = ['user', 'info']
  • 因為import()根據(jù)變量導入只能深入一層文件,如果直接導入user/info,這樣會報錯,需要先拆分然后再拼起來
  • 然后根據(jù)path動態(tài)導入路由,并賦值給子路由的component字段。需要保證/views目錄下有這樣的組件
// 路徑必須以絕對路徑,相對路徑或@開頭,文件名結(jié)尾,vite官網(wǎng)有說明  
// 不符合的話導入報錯  
childRoute.component = () => import(`@/views/${path[0]}/${path[1]}.vue`)  

如果component: 'welcome'

  • 這時候組件的路徑就等于path = ['welcome']
  • 然后動態(tài)導入
childRoute.component = () => import(`@/views/${path[0]}.vue`)  

上面的代碼默認子路由下面沒有子路由了,如果有很多級路由的話,需要做更多的判斷。

經(jīng)過轉(zhuǎn)換已經(jīng)把component轉(zhuǎn)成真正的組件了,轉(zhuǎn)換后的server_route

import DEFAULT_LAYOUT from '@/components/layout.vue'  
  
server_route.value = [  
    {  
        path: '/user',  
        component: DEFAULT_LAYOUT,  
        meta: {menuName: '用戶', order: 1},  
        children: [  
            {  
                path: 'info',  
                name: 'userInfo',  
                component: () => import('@/views/user/info.vue'),  
                meta: {menuName: '個人中心'}  
            }  
        ]  
    }  
]  

這樣再排序一下然后就可以直接添加到router里面了

import { useRouter } from 'vue-router'  
const router = useRouter()  
// 排序  
server_route.value.sort((a, b) => (a?.meta?.order ?? 0) - (b?.meta?.order ?? 0))  
// 遍歷轉(zhuǎn)換好的路由表,添加路由  
server_route.value.map((_route) => router.addRoute(_route))  

生成菜單

有了路由數(shù)據(jù),下面可以生成菜單了,這里只對server_route服務(wù)器返回的數(shù)據(jù)生成菜單,本地定義的路由不會添加到菜單里面

<!-- /components/layout.vue -->  
<template>  
    <div>  
        <nav>  
            <h1>菜單欄</h1>  

            <div style="display: flex; gap: 50px; align-items: flex-end;">  
            <template v-for="menu in server_route">  
                <!-- 顯示多級菜單-->  
                <div v-if="!menu.meta.single">  
                    <h5>{{ menu.meta.menuName }}</h5>  
                    <button  
                        v-for="child in menu.children"  
                        @click="router.push({name: child.name})">  
                        {{ child.meta.menuName }}  
                    </button>  
                </div>  

                <!-- 只顯示一級菜單-->  
                <div v-else>  
                    <button @click="router.push({name: menu.children[0].name})">{{ menu.children[0].meta.menuName }}</button>  
                </div>  
            </template>  
            </div>  
        </nav>  

        <hr>  
        <button v-show="needAddRoutes" @click="login">模擬登錄獲取路由</button>  

        <main>  
            <router-view />  
        </main>  
    </div>  
</template>  

上面的代碼只是演示,實際開發(fā)應(yīng)該定義一個單獨的layout-aside組件專門渲染菜單。

總結(jié)

動態(tài)添加路由只要提前定義好服務(wù)器數(shù)據(jù),約定好格式,做起來還是很簡單的。只要能根據(jù)component字段正確的導入組件就沒什么大問題,
不過這只是一個簡單的示例,實際開發(fā)還是有很多情況要處理的。

到此這篇關(guān)于vue3動態(tài)路由+菜單欄的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)vue3動態(tài)路由+菜單欄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue一次性簡潔明了引入所有公共組件的方法

    Vue一次性簡潔明了引入所有公共組件的方法

    這篇文章主要介紹了Vue一次性簡潔明了引入所有公共組件的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • Vue的H5頁面喚起支付寶支付功能

    Vue的H5頁面喚起支付寶支付功能

    目前項目中比較常用的第三方支付無非就是支付寶支付和微信支付。下面介紹一下Vue中H5頁面如何使用支付寶支付。這篇文章主要介紹了Vue的H5頁面喚起支付寶支付,需要的朋友可以參考下
    2019-04-04
  • 詳解Vue 2中的? initState 狀態(tài)初始化

    詳解Vue 2中的? initState 狀態(tài)初始化

    這篇文章主要介紹了詳解Vue 2中的initState狀態(tài)初始化,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • Vue中使用防抖與節(jié)流的方法

    Vue中使用防抖與節(jié)流的方法

    這篇文章主要為大家介紹了Vue中使用防抖與節(jié)流的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • 基于Vue3+Node.js實現(xiàn)客服實時聊天功能

    基于Vue3+Node.js實現(xiàn)客服實時聊天功能

    想象一下淘寶客服的聊天窗口:你發(fā)消息,客服立刻就能看到并回復(fù),這種即時通訊效果是如何實現(xiàn)的呢?本文我們使用 Vue3 作為前端框架,Node.js 作為后端,通過 WebSocket+ Socket.IO 協(xié)議實現(xiàn)實時通信,需要的朋友可以參考下
    2025-05-05
  • Vue如何使用ElementUI對表單元素進行自定義校驗及踩坑

    Vue如何使用ElementUI對表單元素進行自定義校驗及踩坑

    有一些驗證不是通過input select這樣的受控組件來觸發(fā)驗證條件的 ,可以通過自定義驗證的方法來觸發(fā),下面這篇文章主要給大家介紹了關(guān)于Vue如何使用ElementUI對表單元素進行自定義校驗及踩坑的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • vue3輸入單號和張數(shù)如何自動生成連號的單號

    vue3輸入單號和張數(shù)如何自動生成連號的單號

    最近遇到這樣的需求輸入連號事件,需要在表格中輸入物流單號,物流號碼,生成的數(shù)量,名稱,點擊確定自動生成固定數(shù)量的連號物流單號,本文重點介紹vue3輸入單號和張數(shù),自動生成連號的單號,感興趣的朋友一起看看吧
    2024-02-02
  • vue實現(xiàn)tab欄切換效果

    vue實現(xiàn)tab欄切換效果

    這篇文章主要為大家詳細介紹了vue實現(xiàn)tab欄切換效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • 通過vue-router懶加載解決首次加載時資源過多導致的速度緩慢問題

    通過vue-router懶加載解決首次加載時資源過多導致的速度緩慢問題

    這篇文章主要介紹了vue-router懶加載解決首次加載時資源過多導致的速度緩慢問題,文中單獨給大家介紹了vue router路由懶加載問題,需要的朋友可以參考下
    2018-04-04
  • 基于Vue實現(xiàn)的多條件篩選功能的詳解(類似京東和淘寶功能)

    基于Vue實現(xiàn)的多條件篩選功能的詳解(類似京東和淘寶功能)

    這篇文章主要介紹了Vue多條件篩選功能,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-05-05

最新評論

旅游| 清远市| 溧水县| 繁峙县| 青州市| 博兴县| 桃源县| 博兴县| 曲阳县| 石泉县| 罗田县| 军事| 惠水县| 桐庐县| 甘德县| 黄平县| 封开县| 东光县| 当涂县| 拉萨市| 齐河县| 阿坝县| 吴堡县| 南投县| 竹山县| 罗甸县| 广宗县| 昌图县| 辽中县| 保靖县| 北辰区| 翼城县| 南投市| 西安市| 武安市| 西贡区| 沾益县| 武宁县| 舟山市| 长治市| 巴东县|