vue.js动态面包屑
姣姣酱 人气:0最近在学习vue,正好手上有个项目还是用jquery写的,就自己尝试将这个项目的前端用vue实现,途中遇到了动态面包屑的问题,特此记录一下,如有不对的地方,欢迎指正.
需求描述:
点击左侧的导航,跳转到不同的页面,并且根据导航的路径,动态生成面包屑.面包屑的数据均来自于左侧的导航.
思路:
1.面包屑作为一个单独的组件,在页面中引入.页面的结构如下:
<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> <!--左侧菜单导航,点击这边的菜单,右边的面包屑变化--> <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.面包屑组件的实现:
<!--主要代码实现,样式自己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() { //将面包屑的数据存储在vuex状态中 return this.$store.state.breadCrumbList } }, } </script>
3.每次路由更新的时候,更新面包屑的数据:
//main.js router.beforeEach( (to, from, next) => { //这里用到导航守卫 store.commit('setCurrRouteNme', {currRouteNme:to.name}); store.dispatch('setMenuList').then( ()=> { //因为面包屑的数据来自左侧菜单,这边先获取左侧导航数据然后根据当前路径生成面包屑 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: { //因为数据是异步请求获取的,所以改变state要通过dispatch,commit只能处理同步数据 setMenuList ( {commit} ) { let menuList; return new Promise ( (resolve) => { axios(url).then( res => { //url是请求菜单数据的接口 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 }); //这边是为了左侧菜单而进行的数据处理,可忽略 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 }) } } })
加载全部内容