Vue3-面包屑Breadcrumb开发
【摘要】 Vue3-面包屑Breadcrumb开发
❤ Vue3-面包屑Breadcrumb开发
1. 面包屑组件Breadcrumb
在后台管理之中,面包屑是一个非常重要的组件,它可以帮助用户快速定位当前页面在系统中的位置,并且可以方便地返回到上一级页面。
接下来我们就开发一个面包屑组件Breadcrumb,这里我们使用Element Plus库中的Breadcrumb组件来实现。
2、面包屑组件开发
首先,我们需要在components
文件夹下创建一个Breadcrumb.vue
文件,并在其中编写面包屑组件的代码。
👉 先看看官方给我们提供的案例
<template>
<el-breadcrumb separator=">>>">
<el-breadcrumb-item :to="{ path: '/' }">homepage</el-breadcrumb-item>
<el-breadcrumb-item>
<a href="/">promotion management</a>
</el-breadcrumb-item>
<el-breadcrumb-item>promotion list</el-breadcrumb-item>
<el-breadcrumb-item>promotion detail</el-breadcrumb-item>
</el-breadcrumb>
</template>
👉分割部分设置为iconfont的图标
只需要更改separator-icon
属性即可,这个属性负责控制面包屑的分隔符,设置为ArrowRight
,就可以使用Element Plus库中的ArrowRight
图标作为分隔符。
<template>
<el-breadcrumb :separator-icon="ArrowRight">
<el-breadcrumb-item :to="{ path: '/' }">homepage</el-breadcrumb-item>
<el-breadcrumb-item>promotion management</el-breadcrumb-item>
<el-breadcrumb-item>promotion list</el-breadcrumb-item>
<el-breadcrumb-item>promotion detail</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script lang="ts" setup>
import { ArrowRight } from '@element-plus/icons-vue'
</script>
简单预览一下
3、渲染面包屑
接下来,我们引入面包屑组件,并在其中渲染面包屑。
简单的去匹配一下我们的路由表,然后渲染出来即可,代码如下:
这里需要注意的就是meta中的title
字段,用来表示面包屑的名称,如果没有这个字段,那么这个路由就不会被渲染到面包屑中
<template>
<el-breadcrumb separator="/">
<el-breadcrumb-item v-for="(val,index) in breadcrumbList" :key="val+''+index">
<a href="/admin" v-if="val.path=='/'">首页</a>
<!-- <a v-else-if="val.path=='/admin'"></a> -->
<a :href="val.path" v-else>{{val.meta?.title}}</a>
</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script setup>
import {getCurrentInstance,ref,onMounted} from 'vue'
const { proxy } = getCurrentInstance()// 获取当前实例
const route=proxy.$useRoute();
const breadcrumbList=ref([]);
onMounted(()=>{
breadcrumbList.value=route.matched;
})
</script>
接下来就可以顺利使用了,当然了,接下来继续去完善和优化面包屑部分
4、优化
👉 动态匹配路径
点击不同的路径以后我们发现,面包屑的路径还是之前的,来回切换的过程之中根本无法做到路径与组件一致,那如果我们想动态匹配路径,做到路由与路径一致该怎么做呢?
这里我们捋一下我们的思维,其实我们只需要监听一下地址,然后跟我们的路由做一下匹配,最后路由变化的时候我们再重新渲染一下面包屑即可
监听一下地址
路由做一下匹配
路由变化=> 重新渲染面包屑
👉 对比watch和watchEffect实现
仅仅监听一下路由的话,其实watch和watchEffect都可以实现,本质上就是个监听的行为,我们先看看这两者实现的核心代码应该是啥样的
△ 正常我们两者之间应该如何去监听我们的路由
- watch监听
通常我们用在需要在回调函数中执行复杂的逻辑,或者需要精确地控制回调函数的执行时机
<template>
<div>watch</div>
</template>
<script setup>
import { watch } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
watch(() => route.path, (newPath, oldPath) => {
console.log(`路由地址从 ${oldPath} 变为 ${newPath}`);
});
</script>
- watchEffect监听
通常用在精确地监听特定的数据变化,或者在回调函数中执行复杂的逻辑
<template>
<div>watch</div>
</template>
<script setup>
import { watchEffect } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
watchEffect(() => {
const path = route.path;
console.log(`当前路由地址为 ${path}`);
});
</script>
上面的代码十分简单,接下来我们就利用两者的监听来实现一下我们的面包屑功能,代码如下:
👉 watchEffect初步实现
接下来我们先试用watchEffect进行一个初步的实现,原理上应该是监听路由的变化,然后根据路由的变化来更新面包屑的内容
代码如下:
<template>
<el-breadcrumb separator="/">
<el-breadcrumb-item v-for="(val,index) in breadcrumbList" :key="val+''+index">
<a :href="val.path">{{val.meta?.title}}</a>
</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script setup>
import {getCurrentInstance,ref,onMounted,watch,watchEffect} from 'vue'
const { proxy } = getCurrentInstance()// 获取当前实例
const $route=proxy.$useRoute();
const breadcrumbList=ref([]);
const getBreadcrumb = () => {
let matched = $route.matched.filter(item => item.meta && item.meta.title);
const first = matched[0];
if (!isDashboard(first)) {
matched = [{ path: '/index', meta: { title: '首页' }}].concat(matched);
}
breadcrumbList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false);
};
const isDashboard = (route) => {
const name = route && route.name;
if (!name) {
return false;
}
return name.trim() === 'admin';
};
watchEffect(() => {
const route = $route;
// if you go to the redirect page, do not update the breadcrumbs
if (route.path.startsWith('/redirect/')) {
return;
}
getBreadcrumb();
});
getBreadcrumb();
</script>
再次点击我们发现watchEffect已经生效了,点击的时候也正常,那么watch其实也是可以实现的,我们也利用它来进行一下实现
👉 watch初步实现问题
利用watch实现的话,那他就应该是下面这样子:
<template>
<el-breadcrumb separator="/">
<el-breadcrumb-item v-for="(val,index) in breadcrumbList" :key="val+''+index">
<a :href="val.path">{{val.meta?.title}}</a>
</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script setup>
import {getCurrentInstance,ref,onMounted,watch,watchEffect} from 'vue'
const { proxy } = getCurrentInstance()// 获取当前实例
const $route=proxy.$useRoute();
const breadcrumbList=ref([]);
const getBreadcrumb = () => {
let matched = $route.matched.filter(item => item.meta && item.meta.title);
if (!isDashboard(first)) {
matched = [{ path: '/index', meta: { title: '首页' }}].concat(matched);
}
breadcrumbList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false);
};
const isDashboard = (route) => {
const name = route && route.name;
if (!name) {
return false;
}
return name.trim() === 'admin';
};
watch(() => $route, (route) => {
if (route.path.startsWith('/redirect/')) {
return;
}
getBreadcrumb();
}, { immediate: true });
getBreadcrumb();
</script>
利用watch进行实现但是我们点击的时候路由却没发生变化,什么原因导致的呢
我们先来审查一下代码,watch和watchEffect类似代码,其实没区别,使用watchEffect来进行监听却没有出现这种问题,那为什么会出现这种情况呢
对比发现原因
🔺略微思考一下可以发现:
在监听路由的方式之中我们可以看到,我们监听的是$route,但是实际上我们点击的时候路由是发生了变化的,我们把写法写的更加原生一些试试
<script setup>
import {getCurrentInstance,ref,onMounted,watch,watchEffect} from 'vue'
const { proxy } = getCurrentInstance()// 获取当前实例
import { useRoute } from 'vue-router';
const route = useRoute();
const breadcrumbList=ref([]);
const getBreadcrumb = () => {
let matched = route.matched.filter(item => item.meta && item.meta.title);
const first = matched[0];
if (!isDashboard(first)) {
matched = [{ path: '/index', meta: { title: '首页' }}].concat(matched);
}
breadcrumbList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false);
};
const isDashboard = (route) => {
const name = route && route.name;
if (!name) {
return false;
}
return name.trim() === 'admin';
};
watch(() => route.path, (newPath, oldPath) => {
console.log(`路由地址从 ${oldPath} 变为 ${newPath}`);
if (route.path.startsWith('/redirect/')) {
return;
}
getBreadcrumb();
});
getBreadcrumb();
</script>
再次点击我们发现,很奇怪的事发生了,这会我们点击面包屑的时候,路由已经可以正常发生改变了
👉结论:
上面watch我们监听的是route的值,而不是$route的引用
当然了,写法上watch对比watchEffect的话还是watchEffect更简洁一些,这里我们不需要监听太复杂的逻辑,使用watchEffect更好。
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)