Vue实现首页->列表(列表刷新),列表->详情->列表(列表缓存)

1,611 阅读1分钟

最近有个需求需要实现列表滚动分页,然后点击单个item跳转详情后再返回列表需要保留在原来的位置, 而从其他页面进入到列表页时需要刷新页面。

解决思路主要是keep-alive结合activated生命周期及导航守卫实现

步骤一 在router.js中添加需要缓存的路由,设置meta属性

image.png

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

image.png

<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做如下更改
  1. list.vue结构如下

image.png

<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>
  1. 分别在list.vue的beforeRouteEnter, beforeRouteLeave和activated编辑如下逻辑

image.png

 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()
  },

好了,接下来就可以实现你想要的效果了,希望能帮到各位码农们!