vue.js实现动态面包屑

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Vue动态面包屑功能的实现方法

    面包屑应该是我们在项目中经常使用的一个功能,一般情况下它用来表示我们当前所处的站点位置,也可以帮助我们能够更快的回到上个层级. 今天我们就来聊聊如何在 Vue 的项目中实现面包屑功能.以下案例都是使用 Element-UI 进行实现. 最笨的方式 首先我们想到的最笨的方法就是在每个需要面包屑的页面中固定写好. <template> <div class="example-container"> <el-breadcrumb separator="

  • vue实现动态面包屑导航

    本文实例为大家分享了vue实现动态面包屑导航的具体代码,供大家参考,具体内容如下 动态面包屑导航是根据路由中的 matched 获取到的单独提取出面包屑导航栏组件 <template>   <el-breadcrumb class="app-breadcrumb" separator="/">     <transition-group name="breadcrumb">       <el-bread

  • vue+elementUI动态生成面包屑导航教程

    效果如下所示: 项目需要动态生成面包屑导航,并且首页可以点击.其余为路径显示 <el-menu :unique-opened="true" router :default-active="$route.path" @select="handleSelect"> <div class="user-menu-box" v-for="menu in menus" :key="menu.

  • vue+elementUI实现动态面包屑

    本文实例为大家分享了vue+elementUI实现动态面包屑的具体代码,供大家参考,具体内容如下 引言 后台管理系统中,经常会出现需要面包屑的情况,但是又不想每个页面都实现一个,这样不方便维护,因此封装了面包屑组件,方便在页面使用 封装组件 <!-- Breadcrumb/index.vue -->     <template>   <div>     <el-breadcrumb class="breadcrumb" separator=&q

  • vue动态路由实现多级嵌套面包屑的思路与方法

    前言 最近在工作中遇到了一个问题,是关于vue动态路由多级嵌套面包屑怎么弄(不是动态路由嵌套可以尝试用 this.$route.matched方法获取到path和name集合,动态的嵌套获取不到全部具体的id) 功能比如:A列表页面路由如/a,点击任意一列进入任意一个A的详情页面名字为B,/b/03(这个是动态路由弄是吧,03就是id嘛),点击B页面任意一列,再进入B的详情页名字为C,路由如/bdetail/01;现在弄面包屑要获取到的路由是刚刚打开的,如(/a:/b/03:/bdetail/0

  • vue2.0 elementUI制作面包屑导航栏

    Main.js var routeList = []; router.beforeEach((to, from, next) => { var index = -1; for(var i = 0; i < routeList.length; i++) { if(routeList[i].name == to.name) { index = i; break; } } if (index !== -1) { //如果存在路由列表,则把之后的路由都删掉 routeList.splice(index

  • Vue2+element-ui实现面包屑导航

    本文实例为大家分享了Vue2+element-ui实现面包屑导航的具体代码,供大家参考,具体内容如下 1.面包屑导航栏布局 代码: <template>     <!--面包屑导航页签-->     <div style="padding: 25px 0;flex: 1">         <el-breadcrumb separator-class="el-icon-arrow-right">            

  • VUE+elementui面包屑实现动态路由详解

    我的路由: const routerMap = [ { path: '/', redirect: 'dashboard', component: Layout, name:'Dashboard', children: [ { path: 'dashboard', component: () => import('@/view/dashboard'), name: 'Dashboard', meta: { title: 'dashboard', icon: 'dashboard', noCache

  • vue+elementUI面包屑组件封装方法详解

    本文实例为大家分享了vue+elementUI面包屑组件封装的具体代码,供大家参考,具体内容如下 一.选择用哪种样式 二.在组件文件夹下创建组件 三.在Bread.vue复制如下代码 <template>   <!-- 面包屑 -->   <div class="bread">  <el-breadcrumb separator-class="el-icon-arrow-right">  <el-breadcru

  • vue element-ui实现动态面包屑导航

    vue element-ui动态面包屑导航,供大家参考,具体内容如下 直接上代码 一.template代码 // 这是单独的组件 <template> <el-breadcrumb separator-class="el-icon-arrow-right"> // 首页我是写死的,其他的遍历出来 <el-breadcrumb-item :to="{ name: 'home' }">首页</el-breadcrumb-item

随机推荐