這篇文章主要介紹在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.js
export 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.js
const getters = {
cachePages: state => state.app.cachePages
}
export default getters// src/store/index.js
import 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.js
export 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" >
</div>
</template>
<script>
import { savePosition } from '@/mixins'
export default {
mixins: [new savePosition('scroll-container')]
}
</script>我的小伙伴經常會來問我一個問題,為什么我配置了卻沒有緩存的效果?
這個時候你就需要注意一個問題了,keep-alive的一個關鍵是路由里的name要和.vue文件里的name保持一致。
如果你的緩存沒有生效,請首先檢查一下兩個name和needCachePages里是否一致。
以上是“在vue移動端項目中怎么實現頁面緩存”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。