vue.js實現(xiàn)動態(tài)面包屑
最近在學(xué)習(xí)vue,正好手上有個項目還是用jquery寫的,就自己嘗試將這個項目的前端用vue實現(xiàn),途中遇到了動態(tài)面包屑的問題,特此記錄一下,如有不對的地方,歡迎指正.
需求描述:
點擊左側(cè)的導(dǎo)航,跳轉(zhuǎn)到不同的頁面,并且根據(jù)導(dǎo)航的路徑,動態(tài)生成面包屑.面包屑的數(shù)據(jù)均來自于左側(cè)的導(dǎo)航.
思路:
1.面包屑作為一個單獨的組件,在頁面中引入.頁面的結(jié)構(gòu)如下:
<template> ? ? <div class="page-center"> ? ? ? ? <top-bar></top-bar> <!--頁面頂部信息,固定在頂部--> ? ? ? ? <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)航,點擊這邊的菜單,右邊的面包屑變化--> ? ? ? ? <div class="right-content" ?v-bind:style="{ marginLeft: colspan?'100px':'220px' }"> ? ? ? ? ? ? <bread-crumb></bread-crumb> <!--面包屑組件--> ? ? ? ? ? ? <div class="content"> ? ? ? ? ? ? ? ? <router-view></router-view> <!--路由頁面--> ? ? ? ? ? ? </div> ? ? ? ? ? ?? ? ? ? ? </div> ? ? ? ?? ? ? </div> </template>
2.面包屑組件的實現(xiàn):
<!--主要代碼實現(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ù)存儲在vuex狀態(tài)中 ? ? ? ? ? return this.$store.state.breadCrumbList ? ? ? } ? ? }, } </script>
3.每次路由更新的時候,更新面包屑的數(shù)據(jù):
//main.js router.beforeEach( (to, from, next) => { //這里用到導(dǎo)航守衛(wèi) ? store.commit('setCurrRouteNme', {currRouteNme:to.name}); ? store.dispatch('setMenuList').then( ()=> { //因為面包屑的數(shù)據(jù)來自左側(cè)菜單,這邊先獲取左側(cè)導(dǎo)航數(shù)據(jù)然后根據(jù)當前路徑生成面包屑 ? ? 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: { //因為數(shù)據(jù)是異步請求獲取的,所以改變state要通過dispatch,commit只能處理同步數(shù)據(jù) ? ? setMenuList ( {commit} ) { ? ? ? let menuList; ? ? ? return new Promise ( (resolve) => { ? ? ? ? axios(url).then( res => { //url是請求菜單數(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è)菜單而進行的數(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){ //遞歸找出當前菜單的所有父親菜單 ? ? ? ? ? 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:'首頁', ? ? ? ? ? path:'' ? ? ? }; ? ? ? breadCrumbPre.unshift(index); ? ? ? commit('setBreadCrumb', { ? ? ? ? breadCrumbList:breadCrumbPre ? ? ? }) ? ? } ? ? } })
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue.js添加一些觸摸事件以及安裝fastclick的實例
今天小編就為大家分享一篇vue.js添加一些觸摸事件以及安裝fastclick的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08Vue中使用jsencrypt進行RSA非對稱加密的操作方法
這篇文章主要介紹了Vue中使用jsencrypt進行RSA非對稱加密,在這里需要注意要加密的數(shù)據(jù)必須是字符串,對Vue?RSA非對稱加密相關(guān)知識感興趣的朋友一起看看吧2022-04-04