The introduction of

When developing a SPA using vue + VUe-Router, have you ever encountered a situation where switching between the list page and the detail page, if the list page is not cached, will cause the list page to reload every time it returns from the detail page? The diagram below:

Careful friends have found that when the list page is returned from the details page, the list page is overloaded, such an experience is obviously not good, then we can cache the list page.

Keep-alive implements page caching

Not all pages in our project need to be cached, so here are two ways to cache on demand:

Method one:

A KeepAlive field is used as a KeepAlive field to indicate whether the page is cached.

routes:[{
    path: '/search',
    name: 'search',
    component: search,
    meta: {
        title: 'Search List Page',
        keepAlive: true// Tag list page needs to be cached}}, {path:'/detail',
    name: 'detail',
    component: detail,
    meta: {
        title: 'Details Page'}}}}}}}}Copy the code

The

component does not support the V-if directive, so we use two

expressions in app. vue to determine whether to cache the page through the keepAlive field of the current route:

<div id="app">
    <keep-alive>
        <router-view v-if="$route.meta.keepAlive" />
    </keep-alive>
    <router-view v-if=! ""$route.meta.keepAlive" />
</div>
Copy the code

Method 2

Use the exclude or include option provided by

. Here we use exclude, in app.vue:

<div id="app">
    <keep-alive exclude="detail">
        <router-view />
    </keep-alive>
</div>
Copy the code

Note that it is important to give the page component its name, for example in detail.vue:

<script>
export default {
    name: 'detail'// Exclude is the same as the keep-alive option... } </script>Copy the code

This means that all pages in the project will be cached except for the page component whose name is detail.

Special case optimization:

If the detail page is keep-alive, the scrolling position of the list page and the detail page may affect each other. In this case, we need to provide a scrollBehavior method in the Router instance:

export default new Router({
    scrollBehavior (to, from, savedPosition) {
    	if (savedPosition) {
    		return savedPosition
    	} else {
    		return { x: 0, y: 0 }
    	}
    },
    routes: [...],
})
Copy the code

Results show

However, I expect that whenever I enter a search page from the home page, the page data needs to be reset to its original state. Is there any way to flexibly control whether the page data needs to be reset? That’s when VUex, the state management library in the VUE ecosystem, comes to mind.

Make your page more flexible with Vuex

Requirement analysis: we need a global flag to control whether the data needs to be reset each time a cached page is entered, which vuEX can do.

Vuex make up

The installation

npm install vuex --save
Copy the code

Configuration vuex

To facilitate future maintenance, you can create a store directory to store vuex module code. See the following figure for the directory structure:

state.js:

const state = {
    refreshSearch: true// flag whether to refresh the search page}export default state
Copy the code

mutation.js

const matutaions = {
    setRefreshSearch(state, flag) {
        state.refreshSearch = flag
    }
}
  
export default matutaions
Copy the code

index.js

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'

Vue.use(Vuex)

export default new Vuex.Store({
    state,
    mutations
})
Copy the code

In the entry file main.js:

import store from './store'New Vue({router, store, render: h => h(App)});$mount('#app')
Copy the code

In this way, vuex creates a tag to determine if the page needs to be reset.

Reset the data in your cached pages as much as you want

Where to reset

The keep-alive component has a unique lifecycle hook activated(). Activated () is called every time a keep-alive component is activated, while created() is called only once when a keep-alive component is created and not when it is activated again. So here we need to reset our page data in the Activated () hook.

Reset if you want in Activated ()

The refreshSearch flag in VUEX is used to determine whether a reset is required

Search.vue :(this is the page that needs to be cached)

<script>
import {mapState, mapMutations} from 'vuex'// Vuex provides a mapping function to simplify the codeexport default {
    activated() {
        if(this.refreshSearch) {// if yestrueThis.fetchdata (); }else {
            this.reset(true);
        }
    },
    methods:{
        fetchData() {// get page data},... mapMutations({ reset:'setRefreshSearch'// Map 'this.reset()' to 'this.$store.commit('setRefreshSearch')` }) }, computed: { ... mapState(['refreshSearch'// Map this.refreshSearch to this.$store.state.refreshSearch
        ]),
    }
}
</script>
Copy the code

When we go from the search page to the detail page and want to search the page cache, we simply set the flag to false:

methods: {
    goDetail() {
        this.reset(false// The search page will not reset the data when it returns to the search page.$router.push({path: '/detail'})},... mapMutations({ reset:'setRefreshSearch'})}Copy the code

When we search for a page from the home page and want to reset the page data, simply set the flag to true:

methods: {
    goSearch() {
        this.reset(true// The data will be reset when the page is searched.$router.push({path: '/search'})},... mapMutations({ reset:'setRefreshSearch'})}Copy the code

Results the preview

conclusion

This article introduces the use of Keep-Alive on demand and the use of Vuex to control whether the data of the keep-Alive component page needs to be reset or refreshed.

Knowledge portal: VUE built-in keep-alive

Vue-router Indicates the rolling behavior

Lifecycle Hook Activated

Vuex status management library