,本文通過圖文示例代碼相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下" />

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

vue動(dòng)態(tài)的 BreadCrumb 組件el-breadcrumb ElementUI詳解

 更新時(shí)間:2024年07月18日 10:16:26   作者:十月ooOO  
這篇文章主要介紹了vue如何做一個(gè)動(dòng)態(tài)的 BreadCrumb 組件,el-breadcrumb ElementUI
,本文通過圖文示例代碼相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下

vue 如何做一個(gè)動(dòng)態(tài)的 BreadCrumb 組件 el-breadcrumb ElementUI

一、ElementUI 中的 BreadCrumb 定義

elementUI 中的 Breadcrumb 組件是這樣定義的

<template>
  <el-breadcrumb separator="/">
    <el-breadcrumb-item :to="{ path: '/' }">主頁(yè)</el-breadcrumb-item>
    <el-breadcrumb-item>系統(tǒng)配置</el-breadcrumb-item>
    <el-breadcrumb-item>基礎(chǔ)配置</el-breadcrumb-item>
    <el-breadcrumb-item>自動(dòng)登錄</el-breadcrumb-item>
  </el-breadcrumb>
</template>

效果如圖:

二、實(shí)現(xiàn)原理

我們需要實(shí)現(xiàn)的是,讓它自己通過路由去填寫這部分內(nèi)容
原理是根據(jù)當(dāng)前路由值,拆分成多個(gè)段,然后通過路由 path 去匹配對(duì)應(yīng)的路由名稱,再填入到上面的內(nèi)容中即可。

比如:

1. 當(dāng)前的路由值是 /system/normal-setup/auto-login 2. 通過拆分 / 生成一個(gè)數(shù)組

3. 依次匹配對(duì)應(yīng)的路由名稱

得到這個(gè)數(shù)組之后,依次去路由列表中匹配對(duì)應(yīng)的路由名稱

  • /system 系統(tǒng)配置
  • /system/normal-setup
  • 基礎(chǔ)配置/system/normal-setup/auto-login 自動(dòng)登錄

4. 結(jié)果

這樣就得到了一個(gè) breadCrumb 數(shù)組,直接遍歷這個(gè)數(shù)組,顯示 BreadCrumb 即可

三、具體實(shí)現(xiàn)過程

知道了上面的實(shí)現(xiàn)原理,才會(huì)有具體的實(shí)現(xiàn)過程,這個(gè)過程還是有點(diǎn)麻煩的。

1. 處理路由數(shù)據(jù)

項(xiàng)目中用到的路由數(shù)據(jù)是這樣的樹形結(jié)構(gòu),路由數(shù)據(jù)的定義是這樣的,里面的 children 可以嵌套任意層:

interface MenuEntity {
    id?: number | null,
    parent_id: number,
    name: string,
    icon?: string,
    type: EnumMenuType, // 1->目錄 2->菜單 3->按鈕 4->外鏈
    path: string,
    component?: string,
    visible: EnumMenuVisible, // 1->可見 2->隱藏 默認(rèn)為1
    redirect: string,
    sort: number, // 默認(rèn)為 20
    perm: string, // permission
    created_at?: string,
    updated_at?: string,
    children?: MenuEntity[]
}

實(shí)際的數(shù)據(jù)是這樣的:

{
    "name": "系統(tǒng)配置",
    "id": 10,
    "parent_id": -1,
    "type": 1,
    "path": "/system",
    "component": "",
    "visible": 1,
    "redirect": "",
    "perm": "",
    "sort": 100,
    "icon": "Setting",
    "created_at": "2024-02-26T14:55:12+08:00",
    "updated_at": "2024-02-26T16:12:34+08:00",
    "children": [
        {
            "name": "基礎(chǔ)配置",
            "id": 12,
            "parent_id": -1,
            "type": 1,
            "path": "/system/normal-setup",
            "component": "",
            "visible": 1,
            "redirect": "",
            "perm": "",
            "sort": 10,
            "icon": "CreditCard",
            "created_at": "2024-02-26T15:20:15+08:00",
            "updated_at": "2024-02-26T16:11:56+08:00",
            "children": [
                {
                    "name": "自動(dòng)登錄",
                    "id": 13,
                    "parent_id": 12,
                    "type": 2,
                    "path": "/system/normal-setup/auto-login",
                    "component": "System/NormalSetup/AutoLoginSetup.vue",
                    "visible": 1,
                    "redirect": "",
                    "perm": "",
                    "sort": 30,
                    "icon": "User",
                    "created_at": "2024-02-26T15:24:18+08:00",
                    "updated_at": "2024-05-17T14:11:52+08:00",
                    "children": []
                },
                {
                    "name": "系統(tǒng)更新",
                    "id": 28,
                    "parent_id": 12,
                    "type": 2,
                    "path": "/system/normal-setup/system-update",
                    "component": "System/SystemUpdate.vue",
                    "visible": 1,
                    "redirect": "",
                    "perm": "",
                    "sort": 50,
                    "icon": "UploadFilled",
                    "created_at": "2024-02-26T16:19:49+08:00",
                    "updated_at": "2024-05-17T14:11:39+08:00",
                    "children": []
                },
                {
                    "name": "申請(qǐng)廠家技術(shù)支持",
                    "id": 29,
                    "parent_id": 12,
                    "type": 2,
                    "path": "/system/normal-setup/factory-help",
                    "component": "User/Space.vue",
                    "visible": 1,
                    "redirect": "",
                    "perm": "",
                    "sort": 40,
                    "icon": "SuitcaseLine",
                    "created_at": "2024-02-26T16:20:11+08:00",
                    "updated_at": "2024-03-27T09:04:20+08:00",
                    "children": []
                }
            ]
        }
    ]
}

為了好后續(xù)匹配 path 到路由名,需要將這個(gè)數(shù)據(jù)平化成一個(gè)數(shù)組,并構(gòu)建一個(gè) Map<path, RouteItem> 這樣的一個(gè) Map 數(shù)據(jù),目的是當(dāng)執(zhí)行下面操作時(shí),取到對(duì)應(yīng)的路由數(shù)據(jù)

flatMenuPathNameMap.get('/system')
// 最終取到這樣的數(shù)據(jù)
{
    "name": "系統(tǒng)配置",
    "id": 10,
    "parent_id": -1,
    "type": 1,
    "path": "/system",
    "component": "",
    "visible": 1,
    "redirect": "",
    "perm": "",
    "sort": 100,
    "icon": "Setting",
    "created_at": "2024-02-26T14:55:12+08:00",
    "updated_at": "2024-02-26T16:12:34+08:00",
}

平化樹形數(shù)據(jù)、生成對(duì)應(yīng)的 Map 數(shù)據(jù)結(jié)構(gòu):

/**
 * 菜單相關(guān)
 * 這里是單獨(dú)放到了 pinia 中
 */
export const useMenuStore = defineStore('menuStore', {
    state: () => ({
        menus: [] as Array<RouteRecordRaw>,
        flatMenuArray: [] as Array<MenuEntity>,
        flatMenuPathNameMap: new Map<string, string>()
    }),
    actions: {
        generateMenuArrayAndMap(){
            let menuString = localStorage.getItem('dataMenu')
            let menusCache = menuString ? JSON.parse(menuString) as Array<MenuEntity> : [] as Array<MenuEntity>
            let flatMenuArray = recursionMenuData(menusCache)
            this.flatMenuArray = flatMenuArray
            this.flatMenuPathNameMap = new Map(flatMenuArray.map(item => [item.path, item.name]))
            // 遞歸方法,平化菜單數(shù)據(jù)
            function recursionMenuData(menuArray: Array<MenuEntity>){
                let tempArray: Array<MenuEntity> = []
                menuArray.forEach(item => {
                    if (item.children && item.children.length > 0){
                        tempArray = tempArray.concat(recursionMenuData(item.children))
                        // 添加本身,并去除 children 屬性
                        delete item.children
                        tempArray.push(item)
                    } else {
                        tempArray.push(item)
                    }
                })
                return tempArray
            }
        },
     }
})

使用的時(shí)候

import {useMenuStore, useProjectStore} from "./pinia";
const storeMenu = useMenuStore()
// 當(dāng)執(zhí)行下面的操作時(shí)就會(huì)補(bǔ)全  storeMenu.flatMenuArray 和  storeMenu.flatMenuPathNameMap
storeMenu.generateMenuArrayAndMap()

路由樹的基礎(chǔ)數(shù)據(jù)是這樣的:

平化后的路由數(shù)組是這樣的:

最終生成的 Map 數(shù)據(jù)是這樣的:

2. 拆分當(dāng)前路由 path,并匹配

比如當(dāng)前路由是 /system/normal-setup/auto-login,把它通過 / 拆分之后就是這樣的結(jié)果

import {useRoute} from "vue-router";
const route = useRoute()
let routeSectionArray = route.path.split('/').filter(item => item !== '')
// 這樣拆分之后,前面會(huì)多出一個(gè)空白的 "" ,所以這里剔除了它

接下來要做的就是通過上面的 routerSectionArray 生成下面的幾個(gè)路由組合,再去之前生成的 Map 中匹配對(duì)應(yīng)的路由名即可

  • /system
  • /system/normal-setup
  • /system/normal-setup/auto-login

匹配之后就是這樣的結(jié)果

  • /system 系統(tǒng)配置
  • /system/normal-setup
  • 基礎(chǔ)配置/system/normal-setup/auto-login 自動(dòng)登錄

代碼是這樣的:

import {useRoute} from "vue-router";
import {onMounted, ref} from "vue";
import {useMenuStore} from "@/pinia";
const storeMenu = useMenuStore()
const route = useRoute()
const breadCrumbArray = ref<Array<{name: string, path: string}>>([])
onMounted(()=>{
    let routeSectionArray = route.path.split('/').filter(item => item !== '')
    console.log(routeSectionArray)
    routeSectionArray.forEach((_, index) => {
        let path = `/${routeSectionArray.slice(0,index + 1).join('/')}`
        let pathName = storeMenu.flatMenuPathNameMap.get(path)
        console.log('---',pathName, path)
        if (pathName){
            breadCrumbArray.value.push({name: pathName, path: path})
        }
    })
})

四、搭配其它組件構(gòu)建頁(yè)面

弄好上面的 BreadCrumb 組件之后,就可以不用再管它內(nèi)部的內(nèi)容了,它會(huì)自動(dòng)根據(jù)當(dāng)前路由值生成對(duì)應(yīng)的內(nèi)容。
這樣我們就可以放心的把它放到頁(yè)面結(jié)構(gòu)中了。

比如我的頁(yè)面主要結(jié)構(gòu)是這樣的:

Toolerbar.vue

<template>
    <div class="tool-bar">
        <div class="left">
            <Breadcrumb/>
            <slot name="left"/>
        </div>
        <div class="center">
            <slot name="center"/>
        </div>
        <div class="right">
            <slot name="right"/>
        </div>
    </div>
</template>
<script setup lang="ts">
import Breadcrumb from "@/layout/Breadcrumb.vue";
</script>
<style scoped lang="scss">
.tool-bar{
    padding: 0 20px;
    align-items: center;
    min-height: 50px;
    display: flex;
    flex-flow: row wrap;
    justify-content: space-between;
    .left{
        display: flex;
        flex-flow: row nowrap;
        justify-content: flex-start;
        align-items: center;
        flex-shrink: 0;
    }
    .center{
        display: flex;
        flex-flow: row nowrap;
        justify-content: flex-start;
        align-items: center;
        flex-grow: 1;
        flex-shrink: 0;
    }
    .right{
        display: flex;
        flex-flow: row nowrap;
        justify-content: flex-start;
        align-items: center;
        flex-shrink: 0;
    }
}
</style>

Breadcrumb.vue

<template>
    <el-breadcrumb separator="/">
        <el-breadcrumb-item :to="{ path: '/' }">主頁(yè)</el-breadcrumb-item>
        <el-breadcrumb-item
            v-for="item in breadCrumbArray"
            :key="item">{{ item.name }}</el-breadcrumb-item>
    </el-breadcrumb>
</template>
<script setup lang="ts">
import {useRoute} from "vue-router";
import {onMounted, ref} from "vue";
import {useMenuStore} from "@/pinia";
const storeMenu = useMenuStore()
const route = useRoute()
defineProps( {
    height: { // 高度
        type: Number,
        default: 100
    }
})
const breadCrumbArray = ref<Array<{name: string, path: string}>>([])
onMounted(()=>{
    let routeSectionArray = route.path.split('/').filter(item => item !== '')
    routeSectionArray.forEach((_, index) => {
        let path = `/${routeSectionArray.slice(0,index + 1).join('/')}`
        let pathName = storeMenu.flatMenuPathNameMap.get(path)
        console.log('---',pathName, path)
        if (pathName){
            breadCrumbArray.value.push({name: pathName, path: path})
        }
    })
})
</script>
<style lang="scss" scoped>
@import "../assets/scss/plugin";
</style>

實(shí)際頁(yè)面中使用時(shí)這樣:

<template>
    <Container>
        <Toolbar>
            <template #left>
            </template>
            <template #center>
            </template>
            <template #right>
            </template>
        </Toolbar>
        <Content>
        </Content>
    </Container>
<template>

五、結(jié)果

到此這篇關(guān)于vue 如何做一個(gè)動(dòng)態(tài)的 BreadCrumb 組件,el-breadcrumb ElementUI的文章就介紹到這了,更多相關(guān)vue動(dòng)態(tài)的 BreadCrumb 組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Vue3中Watch監(jiān)聽事件的使用

    詳解Vue3中Watch監(jiān)聽事件的使用

    這篇文章主要為大家詳細(xì)介紹了Vue3中Watch監(jiān)聽事件的使用的相關(guān)資料,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Vue3有一定的幫助,需要的可以參考一下
    2023-02-02
  • Vite多環(huán)境配置項(xiàng)目高定制化能力詳解

    Vite多環(huán)境配置項(xiàng)目高定制化能力詳解

    這篇文章主要為大家介紹了Vite多環(huán)境配置項(xiàng)目高定制化能力詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Antd form表單的使用、設(shè)值、取值、清空值方式

    Antd form表單的使用、設(shè)值、取值、清空值方式

    這篇文章主要介紹了Antd form表單的使用、設(shè)值、取值、清空值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • vue對(duì)象的深度克隆方式

    vue對(duì)象的深度克隆方式

    這篇文章主要介紹了vue對(duì)象的深度克隆方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • nuxt.js中間件實(shí)現(xiàn)攔截權(quán)限判斷的方法

    nuxt.js中間件實(shí)現(xiàn)攔截權(quán)限判斷的方法

    這篇文章主要介紹了nuxt.js中間件實(shí)現(xiàn)攔截權(quán)限判斷的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-11-11
  • vue-router路由懶加載和權(quán)限控制詳解

    vue-router路由懶加載和權(quán)限控制詳解

    這篇文章主要介紹了vue-router路由懶加載和權(quán)限控制的相關(guān)資料
    2017-12-12
  • Vue實(shí)用功能之實(shí)現(xiàn)拖拽元素、列表拖拽排序

    Vue實(shí)用功能之實(shí)現(xiàn)拖拽元素、列表拖拽排序

    在日常開發(fā)中,特別是管理端,經(jīng)常會(huì)遇到要實(shí)現(xiàn)拖拽排序的效果,下面這篇文章主要給大家介紹了關(guān)于Vue實(shí)用功能之實(shí)現(xiàn)拖拽元素、列表拖拽排序的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • 如何在Vue中使用protobuf

    如何在Vue中使用protobuf

    這篇文章主要介紹了如何在Vue中使用protobuf,protobuf是由google推出的和語言無關(guān)和平臺(tái)無關(guān),幾乎支持當(dāng)前的大部分語言,如JavaScript,下文更多相關(guān)介紹需要的小伙伴可以參考一下
    2022-03-03
  • 手寫Vue2.0 數(shù)據(jù)劫持的示例

    手寫Vue2.0 數(shù)據(jù)劫持的示例

    這篇文章主要介紹了手寫Vue2.0 數(shù)據(jù)劫持的示例,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下
    2021-03-03
  • vue實(shí)現(xiàn)的請(qǐng)求服務(wù)器端API接口示例

    vue實(shí)現(xiàn)的請(qǐng)求服務(wù)器端API接口示例

    這篇文章主要介紹了vue實(shí)現(xiàn)的請(qǐng)求服務(wù)器端API接口,結(jié)合實(shí)例形式分析了vue針對(duì)post、get、patch、put等請(qǐng)求的封裝與調(diào)用相關(guān)操作技巧,需要的朋友可以參考下
    2019-05-05

最新評(píng)論

高台县| 通河县| 黄山市| 巴林右旗| 两当县| 会昌县| 太谷县| 张北县| 湘潭县| 华池县| 汉阴县| 威远县| 丰都县| 府谷县| 阿合奇县| 临桂县| 岳阳县| 肥东县| 灵台县| 淮阳县| 绍兴市| 江孜县| 丹棱县| 墨脱县| 金秀| 芦溪县| 德安县| 邢台县| 莲花县| 胶州市| 清涧县| 博野县| 三明市| 平安县| 邳州市| 周宁县| 和政县| 遵化市| 仪征市| 吕梁市| 仙游县|