vue中keep-alive缓存滚动条

前言
这几天公司在做一个app,需要嵌套H5页面,于是H5页面的编写就落到了本人的手里,啥都不说just do it 别逼逼!
项目过程中因为做的页面是列表页和详情页,为了接近原生和用户体验好,所以在列表和详情路由切换时候就要缓存列表页数据(路由跳转就是 列表➡详情返回到➡列表),使用户体验更好
怎么实现
keep-alive

第一步,在路由元信息里配置需要缓存的页面,我用的keepAlive表示,名字随便起,只要和后面的一致即可

// 长期课程
  {
    path: '/perennialClass',
    name: 'perennialClass',
    component: resolve => require(['@/view/course/perennial-class'], resolve),
    meta: {
      title: "长期课程",
      keepAlive: true
    }
  },
  // 短期课程
  {
    path: '/shortPeriodClass',
    name: 'shortPeriodClass',
    component: resolve => require(['@/view/course/short-period-class'], resolve),
    meta: {
      title: "短期课程",
      keepAlive: true
    }
  },
  // 课程详情
  {
    path: '/courseDetails',
    name: 'courseDetails',
    component: resolve => require(['@/view/course/course-details'], resolve),
    meta: {
      title: "课程详情",
      keepAlive: false
    }
  },

第二步,在app.vue中给添加标签,这里是需要缓存的路由,另一个是不需要缓存的


到此就实现了页面的缓存,本来第一天写完下班时候测试的是可以的,第二天上班发现滚动条位置没有缓存,还有一点就是当列表页滚动一定距离以后,进入详情页,详情页也会滚动一定距离,于是乎又寻找其他解方案

2个问题需要解决

  1. 滚动条位置需要记录
  2. 进入详情页的时候页面需要滚动到顶部

解决思路

  1. 针对第一点,我们要在列表页跳入详情页之前记录下当前滚动条位置,等到由详情页返回列表页以后,把刚才记录的滚动条位置恢复。
  2. 针对第二点,在进入详情页时候scrollTop(0);

首先实现记录滚动条位置,我使用vuex记录
在main.js中

import store from './store'

// 结合keep-alive 实现记录列表页滚动条位置
router.beforeEach((to, from, next) => {
  document.title = to.meta.title;
  // 要离开页面如果设置为需要缓存,则本页是要记住上滚动高度到vuex中,以便下次进来恢复高度
  if (from.meta.keepAlive == true) {
    store.commit('recordScroll', document.documentElement.scrollTop || document.body.scrollTop); // document.body.scrollTop一定要加不然iOS上会失效,本人亲测,踩坑
  }
  next()
})
router.afterEach((to, from) => {
  // 如果进入后的页面不想需要缓存,则设置scrollTop = 0
  if (to.meta.keepAlive == false) {
    console.log("不需要缓存");
    setTimeout(() => {
      document.documentElement.scrollTop = 0;
      document.body.scrollTop = 0; // document.body.scrollTop一定要加不然iOS上会失效,本人亲测,踩坑
    }, 10)
  } else {
    console.log("需要缓存" + store.state.scrollTop);
    setTimeout(() => {
      document.documentElement.scrollTop = store.state.scrollTop;
      document.body.scrollTop = store.state.scrollTop; // document.body.scrollTop一定要加不然iOS上会失效,本人亲测,踩坑
    }, 50)
  }
})

vuex代码,在store中

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    scrollTop: 0
  },
  mutations: {
    recordScroll(state, n) {
      state.scrollTop = n
    }
  },
  actions: {

  }
})

到此大功告成,有错误的地方欢迎大神们指正,有不同实现办法的欢迎分享,勿喷!!!谢谢

你可能感兴趣的:(vue-router)