继上一篇,vue+element实现面包屑
上图
其实正常的面包屑只需要用组件直接跳转就行了,可是我的路由带参数,如果不对数据做处理,那么上一级的参数就会丢失
思路:
1、为每一个路由打上标记,比如一级路由就在meta里面写入flag:1,二级写入flag:2,这样就能知道当前面包屑应该展示多少数据
2、新建一个空数组list:[],监听路由,第一次进入页面以及路由发生变化时,都把当前路由的title, path,fullpath 存到 list 里面(我有一个layout.vue是一级页面,其他页面都是他的子页面所以我是在layout进行处理的)
3、这时候只要你不刷新页面,list中的数据就会一直存在,当然了你点击上一级肯定也会继续在数组添加数据,这肯定是不对的,但是我们之前为每一个路由都加了flag,这个就用来截取list,假设我当前访问的是三级页面,已经是最后一级了不应该再继续添加了,那就this.list = this.list.slice(0, this.$route.meta.flag),问题解决不用但心重复了
4、最后展示可以了,刷新数据会丢失,那就把他放到缓存里面详细的看代码
实现:
router举例
{
path: "/manage-product",
name: "product-detail",
meta: {
title: "产品管理",
keepAlive: false,
flag:1,
activeMenu: "/manage-product"
},
component: () => import("@/views/manageproduct")
}
html
<el-breadcrumb separator="/">
<el-breadcrumb-item
v-for="(item, index) in list"
:key="index"
:to="{ path: item.fullPath || item.path}"
>{{item.title}}</el-breadcrumb-item>
</el-breadcrumb>
script
<script>
import { store, mutations } from "@src/store/store"; // 我的缓存
export default {
name: "Layout",
components: { AppMenu, AppHeader, InitLoading },
computed: {
...mapState(["userInfo"])
},
data() {
return {
list: [],
};
},
watch: {
$route(nV, oV) {
this.getBreadcrumb(nV);
}
},
mounted() {
if (store.pathList.length) {// store中有缓存数据就直接使用
console.log(this.$route.meta);
this.list = store.pathList.slice(0, this.$route.meta.flag)
} else { // 没有缓存数据就执行添加面包屑方法
this.getBreadcrumb(this.$route);
}
},
methods: {
getBreadcrumb(obj) {
// 面包屑展示处理
if (!obj) return;
// 根据flag标识判断当时属于几级路由
if (obj.meta.flag && obj.meta.flag != 1) {
// 非一级路由就根据数组push顺序截取到当前路由等级为止,否则数组会一直添加
this.list.push({path:obj.path, title:obj.meta.title, fullPath: obj.fullPath});
this.list = this.list.slice(0, obj.meta.flag);
} else if (obj.meta.flag == 1) {
// 一级路由清空数组之后再添加一次一级路由
this.list = [];
mutations.setBreadList(); // 缓存记得也要清空
this.list.push({path:obj.path, title:obj.meta.title});
}
this.list.map(i => {
if (obj.query.title && i.path == obj.path) {
// 部分页面根据不同状态需要调整title
i.title = obj.query.title;
}
// 将数据放到缓存
mutations.setBreadList({ title: i.title, path: i.path, fullPath:i.fullPath });
});
}
}
};
</script>
我的缓存,不是vuex是Vue.observable
import Vue from 'vue';
import Tools from '../tools/commonRequest/request';
export let store = Vue.observable({
pathList:[], // 用于面包屑记录
});
export let mutations = {
setBreadList(data){
data ? store.pathList.push(data) : store.pathList = []
store.pathList = Tools.deteleObject(store.pathList) // 去重,已经添加过的路由就不再添加了
console.log(store.pathList);
}
}
class Tools {
constructor(params) {
this.firstRouter = ''
this.defaultRouter = ''
}
// 去除重复对象 网上找的
deteleObject(obj) {
var uniques = [];
var stringify = {};
for (var i = 0; i < obj.length; i++) {
var keys = Object.keys(obj[i]);
keys.sort(function (a, b) {
return (Number(a) - Number(b));
});
var str = '';
for (var j = 0; j < keys.length; j++) {
str += JSON.stringify(keys[j]);
str += JSON.stringify(obj[i][keys[j]]);
}
if (!stringify.hasOwnProperty(str)) {
uniques.push(obj[i]);
stringify[str] = true;
}
}
uniques = uniques;
return uniques;
}
}
const tools = new Tools()
export default tools
但是这个时候还存在刷新数据丢失的问题在App.vue写入以下代码
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
import { store, mutations } from "@src/store/store";
export default {
data() {
return {
};
},
created() {
this.loading = true;
// 在页面加载时读取sessionStorage里的状态信息
if (sessionStorage.getItem("store")) {
mutations.setStore(JSON.parse(sessionStorage.getItem("store")))
}
// 在页面刷新时将store.js里的信息保存到sessionStorage里
// beforeunload事件在页面刷新时先触发
window.addEventListener("beforeunload", () => {
sessionStorage.setItem("store", JSON.stringify(store));
});
},
mounted() {
if (sessionStorage.getItem("com")) {
if (sessionStorage.getItem("token")) this.loading = false
} else {
this.loading = false
}
},
methods: {}
};
</script>
好了,完成了