vue移动端项目中如何实现页面缓存的示例代码
背景
在移动端中,页面跳转之间的缓存是必备的一个需求。
例如:首页=> 列表页=> 详情页。
从首页进入列表页,列表页需要刷新,而从详情页返回列表页,列表页则需要保持页面缓存。
对于首页,一般我们都会让其一直保持缓存的状态。
对于详情页,不管从哪个入口进入,都会让其重新刷新。
实现思路
说到页面缓存,在vue中那就不得不提keep-alive组件了,keep-alive提供了路由缓存功能,本文主要基于它和vuex来实现应用里的页面跳转缓存。
vuex里维护一个数组cachePages,用以保存当前需要缓存的页面。
keep-alive 的 includes 设置为cachePages。
路由meta添加自定义字段 needCachePages或keepAlive,needCachePages 为一个数组,表示该路由要进入的页面如果在数组内,则缓存该路由,keepAlive则表示无论进入哪个页面都保持缓存,如app首页这种。
在路由守卫beforeeach里判断,如果要跳转的路由页面在当前路由的needCachePages里,则当前路由添加进cachePages里,反之删除。
具体实现
vuex实现内容
// src/Store/modules/app.jsexport default {
state: {
// 页面缓存数组 cachePages: [] }
, mutations: {
// 添加缓存页面 ADD_CACHE_PAGE(state, page) {
if (!state.cachePages.includes(page)) {
state.cachePages.push(page) }
}
, // 删除缓存页面 REMOVE_CACHE_PAGE(state, page) {
if (state.cachePages.includes(page)) {
state.cachePages.splice(state.cachePages.indexOf(page), 1) }
}
}
}
// src/store/getters.jsconst getters = {
cachePages: state =>
state.app.cachePages}
export default getters// src/store/index.jsimport Vue From 'vue'import Vuex from 'vuex'Vue.use(Vuex)import user from './modules/user'import app from './modules/app'import getters from './getters'// 导出 store 对象export default new Vuex.Store({
getters, modules: {
user, app }
}
)App.vue里,keep-alive的include设置cachePages
keep-alive :include="cachePages">
router-view :key="$route.fullPath">
/router-view>
/keep-alive>
computed: {
...mapGetters([ 'cachePages' ])}
路由配置
{
path: '/home', name: 'Home', component: () =>
import('@/views/tabbar/Home'), meta: {
tITle: '首页', keepAlive: true }
}
,{
path: '/list', name: 'List', component: () =>
import('@/views/List'), meta: {
title: '列表页', needCachePages: ['ListDetail'] }
}
,{
path: '/list-detail', name: 'ListDetail', component: () =>
import('@/views/Detail'), meta: {
title: '详情页' }
}
路由守卫
import Vue from 'vue'import Router from 'vue-router'import store from '@/store'Vue.use(Router)// 导入modules文件夹里的所有路由const files = require.context('./modules', false, /\.js$/)let modules = []files.keys().forEach(key =>
{
modules = modules.concat(files(key).default)}
)// 路由const routes = [ {
path: '/', redirect: '/home', }
, ...modules]const router = new Router({
mode: 'hash', routes: routes}
)function isKeepAlive(route) {
if (route.meta &
&
route.meta.keepAlive) {
store.COMmit('ADD_CACHE_PAGE', route.name) }
if (route.children) {
route.children.forEach(child =>
{
isKeepAlive(child) }
) }
}
routes.forEach(item =>
{
isKeepAlive(item)}
)// 全局路由守卫router.beforeEach((to, from, next) =>
{
if (from.meta.needCachePages &
&
from.meta.needCachePages.includes(to.name)) {
store.commit('ADD_CACHE_PAGE', from.name) }
else if (from.meta.needCachePages) {
store.commit('REMOVE_CACHE_PAGE', from.name) }
// 出现页面首次缓存失效的情况,猜测是vuex到keep-alive缓存有延迟的原因 //这里使用延迟100毫秒解决 setTimeout(() =>
{
next() }
, 100)}
)export default router还原页面滚动条位置
此时虽然页面实现缓存了,但滚动条每次都会重新回到顶部。
对于缓存的页面,会触发activated和deactivated这两个钩子,可以利用这两个钩子来实现还原滚动条位置。
在页面离开时,也就是deactivated触发时记录滚动条位置。
在重新回到页面时,也就是activated触发时还原滚动条位置。
// 创建一个mixin// src/mixins/index.jsexport const savePosition = (scrollId = 'app') =>
{
return {
data() {
return {
myScrollTop: 0 }
}
, activated() {
const target = document.getElementById(scrollId) target &
&
target.scrollTop = this.myScrollTop }
, beforeRouteLeave(to, from, next) {
const target = document.getElementById(scrollId) this.myScrollTop = target.scrollTop || 0 next() }
}
}
这里发现使用deactivated时会因为页面隐藏过快会导致获取的节点滚动条高度为0,所以用beforeRouteLeave。
在需要缓存的页面中使用
script>
import {
savePosition }
from '@/mixins'export default {
mixins: [new savePosition()]}
/script>
如果页面自定义了滚动容器,此时可以传入滚动容器id
template>
div id="scroll-container" style="height: 100vh;
overflow-y: scroll;
">
/div>
/template>
script>
import {
savePosition }
from '@/mixins'export default {
mixins: [new savePosition('scroll-container')]}
/script>
注意
我的小伙伴经常会来问我一个问题,为什么我配置了却没有缓存的效果?
这个时候你就需要注意一个问题了,keep-alive的一个关键是路由里的name要和.vue文件里的name保持一致。
如果你的缓存没有生效,请首先检查一下两个name和needCachePages里是否一致。
思考与不足
此方案是我一年多前的做法,现在想来其实还是存在一些不足的,比如每次都需要去配置路由里的needCachePages。
而实际上在移动端中,往往都是在返回上一页时,上一页始终保持缓存的状态,就如开发小程序时一样,当我们调用navigateTo后再返回,页面始终是缓存的并不需要任何人为的配置。
所以现在的想法是,在vue中提供一个全局的跳转api,只要调用该api就把当前页面缓存,如果需要刷新操作,可以像小程序里的onShow一样在activated里执行你的逻辑。
到此这篇关于vue移动端项目中如何实现页面缓存的示例代码的文章就介绍到这了,更多相关vue 页面缓存内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
您可能感兴趣的文章:- vue页面跳转实现页面缓存操作
- Vue2.0 实现页面缓存和不缓存的方式
- vue项目强制清除页面缓存的例子
- vuex + keep-alive实现tab标签页面缓存功能
- vue服务端渲染页面缓存和组件缓存的实例详解
- Vue项目全局配置页面缓存之按需读取缓存的实现详解
- 详解基于vue的移动web app页面缓存解决方案
- 详解vue之页面缓存问题(基于2.0)
- vue实现页面缓存功能
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: vue移动端项目中如何实现页面缓存的示例代码
本文地址: https://pptw.com/jishu/595008.html
