产品要求:Vue移动端项目进入列表页,列表页需要刷新,而从详情页返回列表页,列表页则需要缓存并且还原页面滚动条位置
建议使用
keep-alive
的includes
属性来做缓存页面
<template>
<div id="app">
<keep-alive>
<router-view class="Router" v-if="$route.meta.keepAlive">router-view>
keep-alive>
<router-view class="Router" v-if="!$route.meta.keepAlive">router-view>
div>
template>
meta
中keepAlive
属性为true
beforeRouteLeave(to, from, next) {
// console.log('777---', from)
this.scroll = document.querySelector('.endInfo').scrollTop
// 离开页面时,需要清除缓存(为了下次进入后刷新页面)
from.meta.keepAlive = false
next()
},
activated() {
// 注意`endInfo`类是:列表box的顶级类,用来计算滚动条的距离
document.querySelector('.endInfo').scrollTop = this.scroll
console.log('缓存页面距离', this.scroll)
},
beforeRouteLeave(to, from, next) {
console.log('支付单详情页', to)
// 设置下一个路由的meta,让列表页面缓存,即不刷新(即:此详情页面返回到sell和customerMangement页面后此页面缓存)
if (to?.path?.includes('sell') || to?.name?.includes('customerMangement')) {
to.meta.keepAlive = true
}
next()
},
解释:
this.$bus
就是在main.js
加上:Vue.prototype.$bus = new Vue()
<template>
<div id="app">
<keep-alive>
<router-view class="Router" v-if="$route.meta.keepAlive" :key="fullPath">router-view>
keep-alive>
<router-view class="Router" v-if="!$route.meta.keepAlive">router-view>
div>
template>
<script>
export default {
name: 'app',
computed: {
fullPath() {
// console.log(this.$route.fullPath);
return this.$route.fullPath;
},
},
mounted() {
console.log('app---mounted')
// 注册监听全局的clearKeepAlive方法,可在其他组件中触发此方法
this.$bus.$on("clearKeepAlive", this.clearKeepAlive);
},
methods: {
// 根据fullUrl清除keepAlive
clearKeepAlive(fullUrl) {
// console.log('bus触发要清除的keepAlive', fullUrl);
this.$children.forEach((item) => {
if (item.$vnode.data.key == fullUrl) {
// console.log('destorykeepAlive', item.$vnode.data.key, fullUrl, item);
this.destorykeepAlive(item);
}
});
},
// 封装清除某个组件的keepAlive状态,并销毁
destorykeepAlive(keepAliveDom) {
if (keepAliveDom?.$vnode?.data?.keepAlive) {
if (keepAliveDom?.$vnode?.parent?.componentInstance?.cache) {
if (keepAliveDom.$vnode.componentOptions) {
var key =
keepAliveDom.$vnode.key == null
? keepAliveDom.$vnode.componentOptions.Ctor.cid +
(keepAliveDom.$vnode.componentOptions.tag
? `::${keepAliveDom.$vnode.componentOptions.tag}`
: "")
: keepAliveDom.$vnode.key;
var cache =
keepAliveDom.$vnode.parent.componentInstance.cache;
var keys = keepAliveDom.$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];
}
}
}
}
keepAliveDom.$destroy();
}
}
script>
beforeRouteLeave(to, from, next) {
if (to.name !== '列表进入的详情页面name') {
// 离开列表页面的时候:当不是进入列表详情页面时清除列表页面的缓存
this.$bus.$emit("clearKeepAlive", from.path)
}
next()
},