实现基于Vue的面包屑导航+连接可跳转组件

简单的来讲,面包屑导航的做用就是告诉用户他们在网站中的位置,方便用户肯定下一步去留,对于用户来讲这是很好的体验。javascript

静态路由-面包屑导航

须要手动配置路由和菜单。css

项目路由以下

const routes = [
 {
    path: '/home1',
    name: 'home1',
    meta: {
      breadID: '0'
    }
  },
  {
    path: '/home2',
    name: 'home2',
    meta: {
      breadID: '0-0'
    }
  },
  {
    path: '/home3',
    name: 'home3',
    meta: {
      breadID: '0-0-0'
    }
  },
  {
    path: '/home4',
    name: 'home4',
    meta: {
      breadID: '1'
    }
  },
  {
    path: '/home5',
    name: 'home5',
    meta: {
      breadID: '1-0'
    }
  },
  {
    path: '/home6',
    name: 'home6',
    meta: {
      breadID: '1-0-0'
    }
  }
]
复制代码

菜单配置以下

面包屑导航有一个层级的菜单。html

let breadNavList = [
    {
        id:"0",
        name:'0-第一级',
        url:'/home1',
        menu:[
            {
                id:'0-0',
                name:'0-第二级',
                url:'/home2',
                menu:[
                  {
                    id:'0-0-0',
                    name:'0-第三级',
                    url:'/home3',
                  }
                ]
            }
        ]
    },
    {
        id:"1",
        name:'1-第一级',
        url:'/home3',
        menu:[
            {
                id:'1-0',
                name:'0-第二级',
                url:'/home4',
                menu:[
                  {
                    id:'1-0-0',
                    name:'0-第三级',
                    url:'/home5',
                  }
                ]
            }
        ]
    }
]
复制代码

能够看到在路由的meta字段中加入了属性breadID,详情解说一下这个属性java

breadID代表当前路由在menu菜单中的位置。git

'0' 当前面包屑有一级,0表明该路由在在菜单栏中的位置breadNavList[0]
'0-0' 表明当前面包屑有两级,breadNavList[0].menu[0]
'0-0-0' 表明当前面包屑有三级,breadNavList[0].menu[0].menu[0]
'0-1-0' 表明当前面包屑有三级,breadNavList[0].menu[1].menu[0]
.....以此类推
复制代码

实现

实现一个容器

数组bread用来装载须要展示的路由。如:github

bread = ['第一级','第二级','第三级']
bread = ['第一级','第二级']
复制代码

效果:npm

第一级 > 第二级 > 第三级
第一级 > 第二级
复制代码

监听路由变化

当路由变化的时候,面包屑也会发生变化。数组

  • 判断当前是否有路由
  • 判断当前路由是否有字段breadID
  • 如如有,调用getBread函数递归获取面包屑
watch:{
      '$route':{
        handler(){
          this.bread = []
          if(this.$route && this.$route.meta && this.$route.meta.breadID){
            let arr = this.$route.meta.breadID.split('-')
            this.getBread(arr,this.breadNavList)
          } else {
            console.error('字段`this.$route.meta.breadID`没有设置')
          }
        },
        immediate:true
      }
    }
复制代码

递归获取面包屑

getBread参数:bash

  • 当前路由属性breadID,转化成数组arr,如:'0-1-0' -> ['0','1','0']
  • 菜单menu,当前层级下的菜单。

思路:函数

  • 获取arr的长度,若是小于0,说明这个层级不存在,不往下递归。
  • 若是大于0,说明层级存在,将这一层的name以及url加入容器bread。
  • 取出arr第一个元素。
  • 循环第一,二,三步,直到arr的长度为0。
getBread(arr,menu){
    if(arr.length < 0){
       return;
    }
    this.bread.push(menu[arr[0]])
    menu = menu[arr[0]].menu
    arr.shift()
    this.getBread(arr,menu)
}
复制代码

所有代码

<template>
  <div class="bread-wrap">
    <div class="bread-item" v-for="(item,index) in bread" :key="index">
      <span @click="toBreadRouter(item)">{{item.name}}</span><i v-if="index !== bread.length - 1"> > </i></div>
  </div>
</template>

<script> export default { name: "breadNav", data() { return { bread:[],//面包屑容器 breadNavList:[]// 面包屑菜单 } }, watch:{ '$route':{ handler(){ this.bread = [] if(this.$route && this.$route.meta && this.$route.meta.breadID){ let arr = this.$route.meta.breadID.split('-') this.getBread(arr,this.breadNavList) } else { console.error('字段`this.$route.meta.breadID`没有设置') } } } }, methods: { getBread(arr,menu){ if(arr.length > 0){ this.bread.push(menu[arr[0]]) menu = menu[arr[0]].menu arr.shift() if(arr.length > 0){ return this.getBread(arr,menu) } } }, toBreadRouter(item){ this.$emit('changeRoute',item) } } } </script>

<style scoped> .bread-wrap{ color:#606266; font-size:14px; } .bread-wrap .bread-item{ display: inline-block; } .bread-wrap .bread-item span:hover{ cursor: pointer; color:#409EFF; } .bread-wrap .bread-item:last-child{ cursor: auto; color:#303133; } .bread-wrap .bread-item:last-child span{ cursor: auto; } .bread-wrap .bread-item i{ font-style: normal; } </style>
复制代码

demo演示

缺点

  • 路由的breadID必须和menu菜单的子项位置一一对应。
  • 若是项目中有两个面包屑,路由的breadID将会混乱。
  • 不适用一个产品可能属于多个类目的项目。(也就是说你根据不一样的类目路径进行点击均可能获得同一个产品。)

总结

该面包屑组件封装上了npm有兴趣的能够下载试试看。gitHub地址-面包屑导航使用教程

相关文章
相关标签/搜索