vue2
、vue3
中页面数据及滚动条缓存(步骤以vue2
为例,vue3
类似):
一、页面数据及滚动条缓存核心代码:
1、在main.js
文件中添加如下代码:
function deduplicateByKey(arr, key) {
const seen = new Set();
return arr.filter((item) => {
const value = item[key];
if (!seen.has(value)) {
seen.add(value);
return true;
}
return false;
});
}
function removeAfterIndex(arr, index) {
if (index < 0 || index >= arr.length) {
console.warn("索引无效,数组保持不变");
return arr;
}
arr.splice(index + 1);
return arr;
}
let history = window.sessionStorage.getItem("history");
if (!history) {
history = "[]";
}
history = JSON.parse(history);
router.beforeEach((to, from, next) => {
const historyLength = history.length;
if (history && history.length > 0) {
history.forEach((item, index) => {
item['pageLevel'] = index + 1;
})
}
if (historyLength >= 2 && history[historyLength - 2].path === to.path) {
console.log("路由后退");
history.pop();
} else {
console.log("路由前进");
to.meta.pageLevel = history.length + 1;
if (history.length === 0 || to.path != history[history.length - 1].path) {
history.push({
path: to.path,
pageLevel: to.meta.pageLevel,
refName: "scrollContainerDiv"
});
}
}
if (to.meta.pageLevel != history[history.length - 1].pageLevel) {
to.meta.pageLevel = history[history.length - 1].pageLevel;
}
window.sessionStorage.setItem("history", JSON.stringify(history));
next();
});
1、定义公共的mixins
,在utils
文件夹下创建mixins
文件夹,并在该文件夹下创建myScrollMinxin.js
文件,myScrollMinxin.js
里的代码如下:
export default {
beforeRouteEnter(to, from, next) {
let refName = to.meta.hasOwnProperty("refName") ? to.meta.refName : "";
next(vm => {
if (from.meta.pageLevel <= to.meta.pageLevel) {
to.meta.scrollTop = 0;
} else {
if (to.meta.hasOwnProperty("scrollTop")) {
vm.$nextTick(() => {
vm.$refs[refName].scrollTop = parseInt(to.meta.scrollTop);
});
}
}
});
},
beforeRouteLeave(to, from, next) {
if (to.meta.hasOwnProperty("refName")) {
let refName = to.meta.refName;
if (from.meta.hasOwnProperty("scrollTop")) {
from.meta.scrollTop = this.$refs[refName].scrollTop;
}
}
if (from.meta.keepAlive && (to.meta.pageLevel <= from.meta.pageLevel) && to.meta.pageLevel != 0) {
if (this.$vnode && this.$vnode.data.keepAlive) {
if (
this.$vnode.parent &&
this.$vnode.parent.componentInstance &&
this.$vnode.parent.componentInstance.cache
) {
if (this.$vnode.componentOptions) {
var key =
this.$vnode.key == null
? this.$vnode.componentOptions.Ctor.cid +
(this.$vnode.componentOptions.tag
? `::${this.$vnode.componentOptions.tag}`
: "")
: this.$vnode.key;
var cache = this.$vnode.parent.componentInstance.cache;
var keys = this.$vnode.parent.componentInstance.keys;
if (cache[key]) {
if (keys.length) {
var index = keys.indexOf(key);
if (index > -1) {
keys.splice(index, 1);
}
}
delete cache[key];
}
}
}
}
this.$destroy();
}
next();
}
};
二、页面数据及滚动条缓存调用步骤如下(代码已封装目前只需要按如下步骤调用即可,若新项目需要页面数据及滚动条缓存可将第一步核心代码引入项目,再调用步骤二):
1、在路由router
文件夹下的index.js
文件中新增自己路由的meta
字段添加如下代码:
meta: {
keepAlive: true,
pageLevel: 0,
refName: "scrollContainerDiv",
scrollTop: 0,
}
2、在需要数据和滚动条缓存的.vue
文件中添加如下代码:
<template>
<div>
//你的代码
//需要滚动部分
<div class="my-compont-box" :ref="$route.meta.refName">
// 1、你的代码没有tab切换的内容 就不需要在
// 2、你的代码有tab切换的内容;类似如下需要在tab切换事件中添加 this.$refs[this.$route.meta.refName].scrollTop = 0:
//(1) <component :is="tabComponents[tabIndex]"></component>
//(2)<组件1 v-if='条件1'></组件1>
// <组件2 v-else-if='条件2'></组件2>
// ...
</div>
</div>
</template>
<script>
//引入封装的 myScrollMinxin.js
import myScrollMinxin from "@/utils/mixins/myScrollMinxin.js";
export default {
//在 mixins 注入自定义的 myScrollMinxin
mixins: [myScrollMinxin],
methods: {
//2、你的代码有tab切换的内容需要在tab切换事件中添加
//this.$refs[this.$route.meta.refName].scrollTop = 0
tabChangeHandler(index){
this.$refs[this.$route.meta.refName].scrollTop = 0
}
}
}
</script>