在移动端用户操作中,经常会遇到列表--详情--列表这种情况,在用户从详情返回列表页面时,如果不缓存的话列表会刷新,给用户带来非常不友好的操作体验,并且也会照成大量的请求。
为了优化体验,vue中设置了keepAlive缓存的组件。可以很好的解决这个问题。
但是如果在详情页操作后会影响列表页某些状态的这种情况下,就需要对列表页的缓存进行设置了。踩了半天的坑,总算解决了这个问题,记录下来分享下,希望遇到此问题的也能快速脱坑。
不说了,上代码:
首先index.js,中定义meta信息
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/pages/home'
// 我的申请
import Applycar from '@/pages/apply/applycar'
import Myapply from '@/pages/apply/myapply'
import Applydet from '@/pages/apply/applydet'
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/applycar',
name: 'applycar',
component: Applycar
},
{
path: '/myapply',
name: 'myapply',
component: Myapply,
meta: {
keepAlive: true, // 需要被缓存
isBack: false //isback是true的时候请求数据,或者第一次进入的时候请求数据
}
},
{
path: '/applydet',
name: 'applydet',
component: Applydet
}
]
})
然后在app.vue中定义keep-aliv
<template>
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>
</template>
列表页的判断逻辑
设置了keepAlive缓存的组件:
第一次进入:beforeRouterEnter ->created->…->activated->…->deactivated
后续进入时:beforeRouterEnter ->activated->deactivated 可以看出,只有第一次进入该组件时,才会走created钩子,而需要缓存的组件中activated是每次都会走的钩子函数。所以,我们要在这个钩子里面去判断,当前组件是需要使用缓存的数据还是重新刷新获取数据。
不过,在activated种判断获取数据后可以将created种获取的入口关闭,否则会请求两次。
data () {
return {
loadshow: false,
loadtext: '加载中',
onFetching: false,
isbounce: true,
Wait_Audit_Num: 0,
PageIndex0: 1,
PageIndex1: 1,
PageIndex2: 1,
mainlist: [],
page: 0,
upobj: {
content: '上拉加载新数据',
pullUpHeight: 60,
height: 40,
autoRefresh: false,
downContent: '放开加载数据',
upContent: '上拉加载新数据',
loadingContent: '加载中...',
clsPrefix: 'xs-plugin-pullup-'
},
scrollerStatus: {
pullupStatus: 'default'
},
isFirstEnter: false, // 是否第一次进入
}
},
created() {
//如果是第一次进入,或者刷新操作的话,也请求数据
this.isFirstEnter = true
//if(this.$route.query.page) {
// this.page = Number(this.$route.query.page)
//} else {
// this.page = 0
//}
//this.getbadge()
// 获取数据
// this.getList()
//if(this.mainlist.length != 0) {
// this.$nextTick(() => {
// this.$refs.scroller.reset()
// })
// }
},
beforeRouteEnter(to, from, next) {
// 判断从导航页面进入,将list的isBack设置为true
// 这样就可以请求数据了
// console.log(from) 在这里,详情页进行审批操作后,路由传参时无法在此处看到的
if (from.name == 'home') {
to.meta.isBack = true
}
next()
},
activated () {
// 路由传参判断是否在详情页面进行了改变状态的操作
console.log(this.$route.query.isfresh)
if (this.$route.meta.isBack || this.isFirstEnter || this.$route.query.isfresh == 0) {
if(this.$route.query.page) {
this.page = Number(this.$route.query.page)
} else {
this.page = 0
}
// 初始化data的参数
this.scrollerStatus.pullupStatus = 'default'
this.isbounce = true
this.onFetching = false
this.Wait_Audit_Num = 0
this.PageIndex0 = 1
this.PageIndex1 = 1
this.PageIndex2 = 1
this.mainlist = []
//请求数据
this.getList()
if(this.mainlist.length != 0) {
this.$nextTick(() => {
this.$refs.scroller.reset()
})
}
this.getbadge()
}
//重新设置当前路由的isBack
this.$route.meta.isBack = false
//重新设置是否第一次进入
this.isFirstEnter = false
},
缓存的页面 created 会执行只有一次,activated每次都会执行 , created 里面做 第一次 isFirstEnter = true(由于页面被缓存,所以一直生效),之后再activated 里面做判断 只有 “不是返回回来的” 和 “第一次进来的” 就刷新数据, 并且要在下面 都设为false, 以免缓存各标识不对,在进入 “列表页” 时,通过router钩子函数 beforeRouteEnter做判断,详情页过来的设 isBack 为true,即不刷新页面
最后在详情页面的操作跳转中去传参
.then(res =>{
this.loadshow = false
this.shztshow = false
this.showdialog = false
var res = JSON.parse(res)
// console.log(res)
if(res.Data.Statu_Code == 200) {
this.$vux.toast.show({
text: res.Data.Msg,
type: 'success',
time: 1000,
onHide () {
self.$router.push({
name: 'myapply',
query: {
page: self.page,
isfresh: 0, // 这里随便传个状态过去,列表页判断有的话,设置列表不缓存
}
})
}
})
} else {
this.$vux.toast.show({
text: res.Data.Msg,
type: 'warn',
time: 3000,
})
}
})
好了。解决问题。如果有帮助,劳烦各位大神点个赞。
如果有更好的方法也可以留言交流。