vue.js實(shí)現(xiàn)動(dòng)態(tài)面包屑
最近在學(xué)習(xí)vue,正好手上有個(gè)項(xiàng)目還是用jquery寫的,就自己嘗試將這個(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)文章
關(guān)于Vue組件庫(kù)開(kāi)發(fā)詳析
這篇文章主要給大家介紹了關(guān)于Vue組件庫(kù)開(kāi)發(fā)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07
解讀vue項(xiàng)目中遇到的深拷貝淺拷貝問(wèn)題
這篇文章主要介紹了vue項(xiàng)目中遇到的深拷貝淺拷貝問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
Vue數(shù)據(jù)綁定簡(jiǎn)析小結(jié)
這篇文章主要介紹了Vue數(shù)據(jù)綁定簡(jiǎn)析小結(jié),本文將從源碼的角度來(lái)對(duì)Vue響應(yīng)式數(shù)據(jù)中的觀察者模式進(jìn)行簡(jiǎn)析。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05
vue.js添加一些觸摸事件以及安裝fastclick的實(shí)例
今天小編就為大家分享一篇vue.js添加一些觸摸事件以及安裝fastclick的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
vue中使用require動(dòng)態(tài)獲取圖片地址方式
這篇文章主要介紹了vue中使用require動(dòng)態(tài)獲取圖片地址方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
Vue中使用jsencrypt進(jìn)行RSA非對(duì)稱加密的操作方法
這篇文章主要介紹了Vue中使用jsencrypt進(jìn)行RSA非對(duì)稱加密,在這里需要注意要加密的數(shù)據(jù)必須是字符串,對(duì)Vue?RSA非對(duì)稱加密相關(guān)知識(shí)感興趣的朋友一起看看吧2022-04-04
Vue中video標(biāo)簽如何實(shí)現(xiàn)不靜音自動(dòng)播放
最近在做大屏展示需要在一開(kāi)始播放引導(dǎo)視頻,產(chǎn)生自動(dòng)播放需求,下面這篇文章主要給大家介紹了關(guān)于Vue中video標(biāo)簽如何實(shí)現(xiàn)不靜音自動(dòng)播放的相關(guān)資料,需要的朋友可以參考下2023-01-01

