Commit 27a9b008 authored by liyan's avatar liyan

7月份文章分享

parent d44389cd
Pipeline #16451 failed with stage
---
title: Vue项目中,路由都被缓存了,特定页面需要自定义刷新规则,怎么办?
date: 2022/07/29 10:42:20
tags:
- 前端
- 路由刷新
- JavaScript
author: 李燕
---
最近开发的几个后台管理系统,都是基于vue-element-admin框架开发的。框架中,默认将所有页面进行了keep-alive缓存。但是在实际需求中,某些页面每次打开都需要刷新数据。这就出现了一个问题:
<!-- more -->
##### ***对于已被缓存的页面,如何进行数据刷新?***
目前,在项目开发中,主要用到以下三种方式:
**一、监听路由,刷新数据**
```js
watch: {
$route: function (newVal) {
if (/data-count\/firmCount/.test(newVal.path)) {
this.init()
}
},
},
```
init()方法中,将页面所有缓存的内容、操作的痕迹都进行了重置,让页面回到初始状态。也就是,每次打开目标页面,都如强制刷新一样,没有任何缓存的痕迹。
**二、利用生命周期函数,刷新数据**
通过keep-alive缓存后的页面,大部分的生命周期函数是不走的。比如:created,mounted等。能够走的生命周期函数就是:activated与deactivated。所以可以在activated生命周期函数中,进行数据刷新。
```js
activated() {
this.init()
},
```
init()方法的写法同上。
**三、利用导航守卫清除缓存,刷新数据**
```js
beforeRouteLeave(to, from, next) {   //参数(马上去的页面,现在的页面,跳转)
    if(判断条件){
         to.meta.keepAlive = false  //将要去的那个页面的缓存清空
    }else{
       to.meta.keepAlive = true   //将要去的那个页面的缓存保留
    }
    next();
  },
```
相对来说,前两种方法比较简单粗暴,哪个页面需要就哪个页面使用,缺点就是每个页面需要重置的内容各不相同,处理比较繁琐。
而第三种方法,我们可以封装成一个公共的方法,在需要的页面引用即可。具体可以参考公司大佬的封装,如下:
```js
//RouteMixin.js
export default {
beforeRouteLeave(to, from, next) { // 离开路由之前执行的函数
if (this.hasCached(from) && this.hasCached(to)) {
const vnode = this.$vnode
const key = vnode.key// 当前关闭的组件名
if (key && vnode.parent) {
const cache = vnode.parent.componentInstance.cache// 缓存的组件
const keys = this.$vnode.parent.componentInstance.keys// 缓存的组件名
if (keys) {
keys.splice(0, keys.length)
}
if (cache) {
for (const k in cache) {
delete cache[k]
}
}
}
}
if (this.hasCached(to)) {
to.meta.keepAlive = true
} else {
to.meta.keepAlive = false
}
next()
},
methods: {
hasCached(route) { // 根据需要定制缓存与否的规则
const matched = route.matched
const current = matched[matched.length - 1]
const parent = current.parent
if (parent && (parent.components.default.name === 'Layout' || parent.components.default.name === 'BlankLayout')) {
return true
}
return false
},
},
}
```
需求是千变万化的,这不,在vue-element-admin项目中,关于页面的缓存刷新,最近又遇到一个新问题:
##### ***对于已被缓存的页面,如何进行前进刷新后退不刷新?***
也就是说,同一个页面,从上级页面或兄弟页面到达时,刷新,从下级页面返回时,不刷新。这应该怎么处理呢?
最终,进行一番搜索,解决如下:
**在beforeRouteLeave中做标记,在activated中根据标记进行刷新与否的处理**
```js
beforeRouteLeave(to, from, next) {
if (to.path === '/data-count/focusGroup') {//去下级页面时打标记
this.$route.meta.isBack = true
} else {
this.$route.meta.isBack = false
}
next()
},
activated() {
if (!this.$route.meta.isBack) {
this.init()
}
},
```
由此,又延申出一个问题:
##### ***从下级页面返回时,页面如何定位到历史位置?***
处理过前进刷新后退不刷新的问题后,这个问题变得相对简单了,我们只需在上述代码的基础上,进行如下处理:
**在beforeRouteLeave中记录scrollTop,在activated中根据记录的scrollTop进行位置处理**
```js
beforeRouteLeave(to, from, next) {
if (to.path === '/data-count/focusGroup') {
this.$route.meta.isBack = true
this.scrollTop = this.$refs.proTable.$el.scrollTop || 0 // 新增的代码
} else {
this.$route.meta.isBack = false
}
next()
},
activated() {
if (!this.$route.meta.isBack) {
this.init()
} else {
this.$refs.proTable.$el.scrollTop = this.scrollTop // 新增的代码
}
},
```
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment