vue.js實(shí)現(xiàn)動(dòng)態(tài)面包屑
最近在學(xué)習(xí)vue,正好手上有個(gè)項(xiàng)目還是用jquery寫(xiě)的,就自己嘗試將這個(gè)項(xiàng)目的前端用vue實(shí)現(xiàn),途中遇到了動(dòng)態(tài)面包屑的問(wèn)題,特此記錄一下,如有不對(duì)的地方,歡迎指正.
需求描述:
點(diǎn)擊左側(cè)的導(dǎo)航,跳轉(zhuǎn)到不同的頁(yè)面,并且根據(jù)導(dǎo)航的路徑,動(dòng)態(tài)生成面包屑.面包屑的數(shù)據(jù)均來(lái)自于左側(cè)的導(dǎo)航.
思路:
1.面包屑作為一個(gè)單獨(dú)的組件,在頁(yè)面中引入.頁(yè)面的結(jié)構(gòu)如下:
<template>
? ? <div class="page-center">
? ? ? ? <top-bar></top-bar> <!--頁(yè)面頂部信息,固定在頂部-->
? ? ? ? <div class="webui-menu-vertical left-nav" ?v-bind:style="{ width:colspan?'100px':'220px' }">
? ? ? ? ? ? <menu-vertical
? ? ? ? ? ? ? ? :menu-list="menuList"
? ? ? ? ? ? ? ? @flexMenuClick="flexMenuClick"
? ? ? ? ? ? ? ? @menuClick="menuClick"></menu-vertical>
? ? ? ? </div> <!--左側(cè)菜單導(dǎo)航,點(diǎn)擊這邊的菜單,右邊的面包屑變化-->
? ? ? ? <div class="right-content" ?v-bind:style="{ marginLeft: colspan?'100px':'220px' }">
? ? ? ? ? ? <bread-crumb></bread-crumb> <!--面包屑組件-->
? ? ? ? ? ? <div class="content">
? ? ? ? ? ? ? ? <router-view></router-view> <!--路由頁(yè)面-->
? ? ? ? ? ? </div>
? ? ? ? ? ??
? ? ? ? </div>
? ? ? ??
? ? </div>
</template>2.面包屑組件的實(shí)現(xiàn):
<!--主要代碼實(shí)現(xiàn),樣式自己DIY-->
<template>
? ? <div class="bread-crumb">
? ? ? ? <ul>
? ? ? ? ? ? <li v-for=" (item, index) in breadCrumbList" :key="item.title">
? ? ? ? ? ? ? ? <router-link>{{item.title}}</router-link>
? ? ? ? ? ? ? ? <span v-if="index < breadCrumbList.length-1">/</span>
? ? ? ? ? ? </li>
? ? ? ? </ul>
? ? </div>
</template>
?
<script>
?
export default {
? ? name:'bread-crumb',
? ? computed: {
? ? ? breadCrumbList() { //將面包屑的數(shù)據(jù)存儲(chǔ)在vuex狀態(tài)中
? ? ? ? ? return this.$store.state.breadCrumbList
? ? ? }
? ? },
}
</script>3.每次路由更新的時(shí)候,更新面包屑的數(shù)據(jù):
//main.js
router.beforeEach( (to, from, next) => { //這里用到導(dǎo)航守衛(wèi)
? store.commit('setCurrRouteNme', {currRouteNme:to.name});
? store.dispatch('setMenuList').then( ()=> { //因?yàn)槊姘嫉臄?shù)據(jù)來(lái)自左側(cè)菜單,這邊先獲取左側(cè)導(dǎo)航數(shù)據(jù)然后根據(jù)當(dāng)前路徑生成面包屑
? ? store.dispatch('setBreadCrumb');
? });
?
? next();
})?
//store.js
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
?
Vue.use(Vuex)
?
export default new Vuex.Store({
? state: {
? ? currRouteNme: String,
? ? oriMenuList:Array,
? ? menuList:Array,
? ? breadCrumbList:Array,
? },
?
? mutations: {
? ? setCurrRouteNme( state, payload ) {
? ? ? state.currRouteNme = payload.currRouteNme
? ? },
?
? ? setMenuList( state, payload) {
? ? ? state.menuList = payload.menuList
? ? },
?
? ? setOriMenuList( state, payload) {
? ? ? state.oriMenuList = payload.oriMenuList
? ? },
?
? ? setBreadCrumb( state, payload) {
? ? ? state.breadCrumbList = payload.breadCrumbList
? ? },
?
? },
? actions: { //因?yàn)閿?shù)據(jù)是異步請(qǐng)求獲取的,所以改變state要通過(guò)dispatch,commit只能處理同步數(shù)據(jù)
? ? setMenuList ( {commit} ) {
? ? ? let menuList;
? ? ? return new Promise ( (resolve) => {
? ? ? ? axios(url).then( res => { //url是請(qǐng)求菜單數(shù)據(jù)的接口
? ? ? ? ? menuList = res.data.authList.map(({id,symbol,pId,forward,resName,isLeaf})=>{
? ? ? ? ? ? return {
? ? ? ? ? ? ? id,
? ? ? ? ? ? ? symbol,
? ? ? ? ? ? ? pId,
? ? ? ? ? ? ? forward,
? ? ? ? ? ? ? label:resName,
? ? ? ? ? ? ? isLeaf:isLeaf,
? ? ? ? ? ? ? icon:isLeaf == 1?'':'el-icon-goods'
? ? ? ? ? ? }
? ? ? ? ? });
?
? ? ? ? ? commit('setOriMenuList', {
? ? ? ? ? ? oriMenuList: menuList
? ? ? ? ? });
? ? ? ? //這邊是為了左側(cè)菜單而進(jìn)行的數(shù)據(jù)處理,可忽略
? ? ? ? let menuTree = menuList.reduce(function (prev, item) {
? ? ? ? ? ? prev[item.pId] ? prev[item.pId].push(item) : prev[item.pId] = [item];
? ? ? ? ? ? return prev;
? ? ? ? ? }, {});
? ? ? ? ??
? ? ? ? ? for (let parentItem in menuTree) {
? ? ? ? ? ? menuTree[parentItem].forEach(function (item) {
? ? ? ? ? ? ? ? item.children = menuTree[item.id] ? menuTree[item.id] : null;
? ? ? ? ? ? });
? ? ? ? ? }
? ? ? ? ??
? ? ? ? ? commit('setMenuList', {
? ? ? ? ? ? menuList: menuTree[0]
? ? ? ? ? });?
?
? ? ? ? ? resolve();
? ? ? ? })
? ? ? })
??
? ? },
?
? ? setBreadCrumb ( {commit, state} ) {
?
? ? ? let currMenuList = state.oriMenuList;
? ? ? let currMenu;
? ? ? let breadCrumbPre = [];
??
? ? ? for (let i=0; i<currMenuList.length; i++) {
? ? ? ? ? if(currMenuList[i]['symbol'] == state.currRouteNme){
? ? ? ? ? ? currMenu = currMenuList[i];
? ? ? ? ? ? ? let breadCrumbItem = {};
? ? ? ? ? ? ? breadCrumbItem.title = currMenuList[i].label;
? ? ? ? ? ? ? breadCrumbItem.path = '';
? ? ? ? ? ? ? breadCrumbPre.unshift(breadCrumbItem);
? ? ? ? ? }
? ? ? }
? ? ? function setBreadCrumb(menu){ //遞歸找出當(dāng)前菜單的所有父親菜單
? ? ? ? ? if(menu.pId != 0){
? ? ? ? ? ? ? for (let i=0; i<currMenuList.length; i++) {
? ? ? ? ? ? ? ? if(currMenuList[i]['id'] == menu.pId){
? ? ? ? ? ? ? ? ? let breadCrumbItem = {};
? ? ? ? ? ? ? ? ? breadCrumbItem.title = currMenuList[i]['label'];
? ? ? ? ? ? ? ? ? breadCrumbItem.path = '';
? ? ? ? ? ? ? ? ? breadCrumbPre.unshift(breadCrumbItem);
? ? ? ? ? ? ? ? ? setBreadCrumb(currMenuList[i])
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? ? }
? ? ? setBreadCrumb(currMenu);
? ? ? let index = {
? ? ? ? ? title:'首頁(yè)',
? ? ? ? ? path:''
? ? ? };
? ? ? breadCrumbPre.unshift(index);
? ? ? commit('setBreadCrumb', {
? ? ? ? breadCrumbList:breadCrumbPre
? ? ? })
? ? }
?
? }
})以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue前端獲取/切換麥克風(fēng)、播放采集音頻和采集音量大小完整代碼
這篇文章主要給大家介紹了關(guān)于vue前端獲取/切換麥克風(fēng)、播放采集音頻和采集音量大小的相關(guān)資料,文中通過(guò)圖文以及代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-12-12
Vue在H5 項(xiàng)目中使用融云進(jìn)行實(shí)時(shí)個(gè)人單聊通訊
這篇文章主要介紹了Vue在H5 項(xiàng)目中使用融云進(jìn)行實(shí)時(shí)個(gè)人單聊通訊,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
前端配合后端實(shí)現(xiàn)Vue路由權(quán)限的方法實(shí)例
一開(kāi)始我還以為vue的路由只能用在工程化的項(xiàng)目里面,其實(shí)不然,下面這篇文章主要給大家介紹了關(guān)于前端配合后端實(shí)現(xiàn)Vue路由權(quán)限的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
vue-cli-service build 環(huán)境設(shè)置方式
這篇文章主要介紹了vue-cli-service build 環(huán)境設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2023-01-01
詳解vue3+element-plus實(shí)現(xiàn)動(dòng)態(tài)菜單和動(dòng)態(tài)路由動(dòng)態(tài)按鈕(前后端分離)
本文需要使用axios,路由,pinia,安裝element-plus,并且本文vue3是基于js而非ts的,這些環(huán)境如何搭建不做描述,需要讀者自己完成,感興趣的朋友跟隨小編一起看看吧2023-11-11
詳解關(guān)于element級(jí)聯(lián)選擇器數(shù)據(jù)回顯問(wèn)題
這篇文章主要介紹了詳解關(guān)于element級(jí)聯(lián)選擇器數(shù)據(jù)回顯問(wèn)題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-02-02
vue 中 beforeRouteEnter 死循環(huán)的問(wèn)題
這篇文章主要介紹了vue beforeRouteEnter 死循環(huán)的問(wèn)題,在文章末尾給大家補(bǔ)充介紹了vue中beforeRouteEnter使用的誤區(qū),需要的朋友可以參考下2019-04-04

