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