本文已参与「新人创作礼」活动,一起开启掘金创作之路
\项目场景:
demo练习,记录所实现的功能;
效果展示:
v2实现面包屑导航
步骤如下: ps : vue2使用的ui框架为element ui
- 将面包屑封成组件(关于组件的封装不做赘述了)
- 封装方法 caleBreadcrumb方法;代码如下:
caleBreadcrumb() {
const temp = []
this.$route.matched.forEach((item) => {
if (item.meta.title && item.path) {
temp.push({ path: item.path, title: item.meta.title })
}
})
this.breadcrumbList = temp // this.breadcrumbList --> data声明的变量
}
$route.matched : 返回一个数组,包含当前路由的所有嵌套路径片段的路由记录 ; 见下方代码片段(来源于官网案例) :
const router = new VueRouter({
routes: [
// 下面的对象就是路由记录
{
path: '/foo',
component: Foo,
children: [
// 这也是个路由记录
{ path: 'bar', component: Bar }
]
}
]
})
3. 动态渲染面包屑组件
代码如下
<template>
<el-breadcrumb separator="/">
<el-breadcrumb-item
:to="{ path: item.path }"
v-for="item in breadcrumbList"
:key="item.title"
>{{ item.title }}</el-breadcrumb-item
>
</el-breadcrumb>
</template>
4. ps : 需要在 created中调用该方法进行初次渲染; 在watch进行监听,当前路由发生变化时调用该方法,重新计算面包屑数据; 下方为完整代码展示
<template>
<el-breadcrumb separator="/">
<el-breadcrumb-item
:to="{ path: item.path }"
v-for="item in breadcrumbList"
:key="item.title"
>{{ item.title }}</el-breadcrumb-item
>
</el-breadcrumb>
</template>
<script>
export default {
data() {
return {
breadcrumbList: []
}
},
methods: {
caleBreadcrumb() {
const temp = []
this.$route.matched.forEach((item) => {
if (item.meta.title && item.path) {
temp.push({ path: item.path, title: item.meta.title })
}
})
this.breadcrumbList = temp
}
},
created() {
this.caleBreadcrumb() //初始化渲染面包屑导航
},
watch: {
// 写法 一 :
// '$route.path'() {
// this.caleBreadcrumb() //路由变化后重新进行计算
// }
// 写法二 :
'$route.path': {
handler() {
this.caleBreadcrumb()
},
immediate: true
}
}
}
</script>
<style lang="scss" scoped></style>
以上为 vue 2.0 版本的面包屑功能实现; 在过程中会出现一个路由重复报错的问题 :
vue-router.esm.js?8c4f:2065 Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location: "/article/ranking".
是因为当前所在页面已经是("/article/ranking".),再次点击就会导致控制台报错;
解决方法如下 :
// 解决路由重复报错的问题
const routerPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return routerPush.call(this, location).catch((error) => error)
}
const routerReplace = VueRouter.prototype.replace
VueRouter.prototype.replace = function replace(location) {
routerReplace.call(this, location).catch((error) => error)
}
v3实现面包屑导航:
ps : vue3+element-plus
vue3 实现面包屑导航的主要区别在于以下几点,其实大致的实现思路是一致的
- vue3使用的是composition API, 所以使用到的 ref,watch..等配置项都需要进行引入;且vue3里不再有this指向问题; 具体的区别可以上官网了解
- breadcrumbList 的定义上,这里使用的是 ref进行定义.没有使用 reactive定义是因为会存在一些小bug,代码量会增加; (感兴趣的话可以尝试一下)
- watch的使用与vue2也不同 ; 也可以自行了解;
直接附完整代码:
<template>
<el-breadcrumb separator="/">
<el-breadcrumb-item
:to="{ path: item.path }"
v-for="item in breadcrumbList"
:key="item.title"
>{{ item.meta.title }}
</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script setup>
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'
// 面包屑导航功能
const route = useRoute()
const breadcrumbList = ref([])
const caleBreadcrumb = () => {
breadcrumbList.value = route.matched.filter(
(item) => item.meta && item.meta.title
)
}
watch(
() => route.path, // 也可以直接写 route ; 即 () => route.path 替换成 route
() => {
caleBreadcrumb()
},
{
immediate: true
}
)
</script>
<style lang="scss" scoped></style>
总结 :
以上为 vue2,vue3实现面包屑导航功能的基本描述,如有不恰当之处欢迎指正;