Sample code on how to implement page caching in vue mobile project

Sample code on how to implement page caching in vue mobile project

background

On mobile devices, caching between page jumps is an essential requirement.

For example: Home page => List page => Details page.

When entering the list page from the home page, the list page needs to be refreshed, and when returning to the list page from the detail page, the list page needs to keep the page cache.

For the home page, we usually keep it in cached state.

For the details page, it will be refreshed no matter which entrance you enter from.

Implementation ideas

Speaking of page caching, we have to mention the keep-alive component in vue. keep-alive provides routing caching function. This article mainly uses it and vuex to implement page jump caching in the application.

Vuex maintains an array cachePages to save the pages that currently need to be cached.
The keep-alive includes are set to cachePages.
Add custom fields needCachePages or keepAlive to the route meta. needCachePages is an array, which means that if the page to be entered by the route is in the array, the route will be cached. keepAlive means that no matter which page is entered, the cache will be kept, such as the homepage of the app.
In the routing guard beforeEach, if the routing page to be jumped is in the needCachePages of the current route, the current route is added to cachePages, otherwise it is deleted.

Specific implementation

Vuex implementation content

// src/store/modules/app.js

export default {
 state: {
  // Page cache array cachePages: []
 },
 
 mutations:
  // Add cache page ADD_CACHE_PAGE(state, page) {
   if (!state.cachePages.includes(page)) {
    state.cachePages.push(page)
   }
  },
  
  // Delete cache 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'

// Export the store object export default new Vuex.Store({
 getters,
 modules:
  user,
  app
 }
})

In App.vue, keep-alive include sets cachePages

<keep-alive :include="cachePages">
 <router-view :key="$route.fullPath"></router-view>
</keep-alive>

computed: {
 ...mapGetters([
  'cachePages'
 ])
}

Routing Configuration

{
  path: '/home',
  name: 'Home',
  component: () => import('@/views/tabbar/Home'),
  meta: {
   title: 'Homepage',
   keepAlive: true
  }
},
{
  path: '/list',
  name: 'List',
  component: () => import('@/views/List'),
  meta: {
   title: 'List Page',
   needCachePages: ['ListDetail']
  }
},
{
  path: '/list-detail',
  name: 'ListDetail',
  component: () => import('@/views/Detail'),
  meta: {
   title: 'Details page'
  }
}

Route Guard

import Vue from 'vue'
import Router from 'vue-router'
import store from '@/store'
Vue.use(Router)

// Import all routes in the modules folder const files = require.context('./modules', false, /\.js$/)
let modules = []
files.keys().forEach(key => {
 modules = modules.concat(files(key).default)
})

// Routing 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)
})

// Global routing guard 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)
 }
 // The first cache failure of the page occurs. It is speculated that there is a delay from vuex to keep-alive cache. //Here, a delay of 100 milliseconds is used to solve setTimeout(() => {
  next()
 }, 100)
})

export default router

Restore the page scroll bar position

Although the page is cached at this time, the scroll bar will return to the top every time.

For cached pages, the activated and deactivated hooks will be triggered, and these two hooks can be used to restore the scroll bar position.

When the page is left, that is, when deactivated is triggered, the scroll bar position is recorded.

When you return to the page, that is, when activated is triggered, the scroll bar position is restored.

// Create a 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()
  }
 }
}

It is found here that when deactivated is used, the page will be hidden too quickly, causing the obtained node scroll bar height to be 0, so beforeRouteLeave is used.

Use it in pages that need to be cached

<script>
import { savePosition } from '@/mixins'

export default {
 mixins: [new savePosition()]
}
</script>

If the page customizes the scroll container, you can pass in the scroll container 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>

Notice

My friends often ask me a question: why is there no caching effect after I configure it?

At this time you need to pay attention to one issue. One of the keys to keep-alive is that the name in the route must be consistent with the name in the .vue file.

If your cache does not take effect, please first check whether the two names and needCachePages are consistent.

Thoughts and shortcomings

This solution is what I did more than a year ago. Now I think there are still some shortcomings, such as the need to configure needCachePages in the route every time.

In fact, on mobile devices, when you return to the previous page, the previous page is always cached, just like when developing a mini-program. When we call navigateTo and then return, the page is always cached and does not require any manual configuration.

So the idea now is to provide a global jump API in Vue. As long as the API is called, the current page will be cached. If a refresh operation is required, you can execute your logic in activated like onShow in the mini program.

This concludes this article on how to implement page caching in a Vue mobile project. For more Vue page caching content, please search for previous articles on 123WORDPRESS.COM or continue browsing the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Vue page jump to achieve page cache operation
  • How to implement page caching and non-caching in Vue2.0
  • Example of forcibly clearing the page cache in a Vue project
  • vuex + keep-alive to implement tab page caching function
  • Detailed example of Vue server-side rendering page cache and component cache
  • Detailed explanation of the implementation of on-demand cache reading in Vue project global configuration page cache
  • Detailed explanation of the mobile web app page caching solution based on Vue
  • Detailed explanation of Vue's page cache problem (based on 2.0)
  • Vue implements page caching function

<<:  How to install Chrome browser on CentOS 7

>>:  Solution to MySQL being unable to start due to excessive memory configuration

Recommend

Detailed steps for installing MySQL using cluster rpm

Install MySQL database a) Download the MySQL sour...

A very detailed tutorial on installing rocketmq under Docker Desktop

Install Docker Desktop Download address: Docker D...

MySQL foreign key constraint (FOREIGN KEY) case explanation

MySQL foreign key constraint (FOREIGN KEY) is a s...

Detailed explanation of lazy loading and preloading of webpack

Table of contents Normal loading Lazy Loading Pre...

Detailed explanation of software configuration using docker-compose in linux

Preface This article will share some docker-compo...

Solution to MySQL root password error number 1045

Stop MySQL Service Windows can right-click My Com...

MySQL uses custom sequences to implement row_number functions (detailed steps)

After reading some articles, I finally figured ou...

Install Docker on Centos7 (2020 latest version available, just copy and paste)

Refer to the official documentation here for oper...

HTML implementation of a simple calculator with detailed ideas

Copy code The code is as follows: <!DOCTYPE ht...

MySQL Basic Tutorial: Detailed Explanation of DML Statements

Table of contents DML statements 1. Insert record...

How to explain TypeScript generics in a simple way

Table of contents Overview What are Generics Buil...