antd-vue3 实现面包屑
面包屑应该是我们在项目中经常使用的一个功能,一般情况下它用来表示我们当前所处的站点位置,也可以帮助我们能够更快的回到上个层级。下面我将根据路由,动态的实现面包屑组件 为了获取到对于的路由信息 可以把相关信息写在路由对应的meta里 我这里用到了title 和icon
路由配置 类似这种
{
path: '/monitor',
name: 'monitor',
meta: { title: '监控中心', icon: 'video' },
component: () => import(/* webpackChunkName: "monitor" */ '@/view/monitor/index.vue'),
redirect: '/monitor/video',
children: [
{
path: 'video',
name: 'video',
meta: { title: '监控中心' },
component: () => import(/* webpackChunkName: "video" */ '@/view/monitor/Monitor.vue'),
},
// 视频档案的路由
{
path: 'video-files',
name: 'video-files',
meta: { title: '视频档案' },
component: () => import(/* webpackChunkName: "video-files" */ '@/view/monitor/components/VideoFiles.vue'),
},
}
这里是面包屑组件完整代码
<template>
<a-breadcrumb class="breadcrumb" separator=">" :routes="routes">
<template #itemRender="itemRender">
<router-link :to="itemRender.redirect ? itemRender.redirect : itemRender.route.path">
<sdFeatherIcons
size="18"
v-if="itemRender.route.meta.icon && itemRender.route.meta.title !== '塔机管理'"
class="menu-img"
:type="itemRender.route.meta.icon"
/>
//这里是为了icon和img混用
<img
class="menu-img"
v-if="itemRender.route.meta.title === '塔机管理'"
:src="require('../static/img/tsqzj.png')"
alt=""
/>
{{ itemRender.route.meta.title }}
</router-link>
</template>
</a-breadcrumb>
</template>
<script>
import { defineComponent, ref, watch, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import { getItem, setItem } from '@/utility/localStorageControl';
//对路由信息进行存储 防止刷新页面 参数丢失
export default defineComponent({
setup() {
onMounted(() => {
if (getItem('breadcrumbList')) {
routes.value = getItem('breadcrumbList');
}
});
const routes = ref([]);
const duplicateRemoval = Arr => {
var hash = {};
Arr = Arr.reduce(function (arr, current) {
console.log(20, current);
hash[current.meta.title] ? '' : (hash[current.meta.title] = true && arr.push(current));
return arr;
}, []);
console.log(23, Arr);
return Arr;
};
const getBreadcrumb = () => {
let matched = route.matched;
matched = duplicateRemoval(matched);
routes.value = [];
//如果不是首页
matched.forEach(item => {
item.children = [];
if (item.path == '/' || item.meta.title == '') return;
// if (item.children.length > 0 && item.redirect == '') return;
routes.value.push(item);
});
setItem('breadcrumbList', routes.value);
};
const route = useRoute();
//监听路由变化
watch(
() => route.path,
() => {
getBreadcrumb();
console.log('watch', routes);
},
);
return {
routes,
};
},
});
</script>
<style scoped>
.breadcrumb {
position: absolute;
top: 39px;
z-index: 2;
padding: 10px 0 0 15px;
font-size: 16px;
}
.breadcrumb .router-link-active {
color: rgba(0, 0, 0, 0.45);
}
.breadcrumb span:last-child .router-link-active {
color: rgba(0, 0, 0, 0.85) !important;
}
.menu-img {
display: inline-block;
width: 20px;
height: 20px;
vertical-align: sub;
}
</style>