最近在学习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
      })
    }

  }
})

 

Logo

前往低代码交流专区

更多推荐