最近有个需求需要实现列表滚动分页,然后点击单个item跳转详情后再返回列表需要保留在原来的位置, 而从其他页面进入到列表页时需要刷新页面。
解决思路主要是keep-alive结合activated生命周期及导航守卫实现
步骤一 在router.js中添加需要缓存的路由,设置meta属性

{
path: '/list',
name: 'list',
component: () => import('@/pages/list/index'),
meta: {
keepAlive: true
}
},
{
path: '/detail',
name: 'detail',
component: () => import('@/pages/detail/index')
},
步骤二 修改App.vue

<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>
步骤三 对列表list.vue做如下更改
- list.vue结构如下

<template>
<div class="list-page">
<div class="header-section" @click="goBack">顶部</div>
<div class="list-wrap" ref="listWrap" :style="{scrollBehavior: needScroll ? 'smooth' : 'auto'}">
<van-list
v-model="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
>
<van-cell @click="goDetail(item)" v-for="(item, index) in list" :key="index" :title="item" />
</van-list>
</div>
<div class="footer-section" @click="toTop">底部</div>
</div>
</template>
- 分别在list.vue的beforeRouteEnter, beforeRouteLeave和activated编辑如下逻辑

data () {
return {
list: [],
loading: true,
finished: false,
scrollTop: 0,
fromUrl: '',
listWrapScrollTop: 0,
needScroll: false
}
},
activated(){
if(this.fromUrl !== '/detail'){
console.log('要刷新了');
this.list = []
this.loading = true
this.finished = false
this.onLoad()
} else {
this.$refs.listWrap.scrollTop = this.listWrapScrollTop
}
this.fromUrl = ''
},
beforeRouteEnter(to,from,next){
next(vm=>{
vm.needScroll = false
if(from.path === '/detail'){
vm.fromUrl = '/detail'
}
})
next()
},
beforeRouteLeave(to,from,next){
if(to.path === '/detail'){
let listWrap = this.$refs.listWrap
let listWrapScrollTop = listWrap.scrollTop
this.listWrapScrollTop = listWrapScrollTop
}
next()
},
好了,接下来就可以实现你想要的效果了,希望能帮到各位码农们!