When you are developing multi-tab applications on the Web using Vue + Element, most of them need to be cached. Keep-alive is well implemented by configuring router.js
The principle of
The Keep-Alive API provided by Vue implements caching of routing components. The include attribute can be bound to an array containing the name value of the component that needs to be routed. If the component does not need to be cached, it can be removed.
Code organization and design
To achieve the above functions, vuEX is used for global cache data saving, defined as cacheView; The open routing page is saved with toolBarData. Below is the overall code design:
To add a route page to the cacheView, you need an Actions setCacheView to commit a change Event to change the state data, The modified data is then automatically distributed to the location (i.e. Keep-alive) where the data was used in app.vue. Adding a TAB is a similar process and is no longer described. There are two main reasons why you want to separate the TAB and the routing cache into two arrays:
The name comparison is used to determine whether to cache. If the name does not match, it is not cached by default
Entry file cache route
In the app. vue entry file, use keep-alive to cache the matching route components, listen for the current route changes, and add cached routes and labels.
<template> <el-main style="position:relative; margin-top:45px;" > <! <div class="routeWrap"> <transition name=" favel-transform "> <keep-alive :include="cachedViews"> <router-view></router-view> </keep-alive> </transition> </div> </el-main> </template> <script> export default { watch: $route() {$route() {const componentName = this.$route. Matched [0]["components"]["default"]["name"]; const detail = this.$route.path; Const name = this.$route.meta[0]["name"]; this.$store.dispatch("commitToolBar", { name, detail, componentName }); } } } </script>Copy the code
About store code
The store code implementation is shown below. The main thing that needs to be explained in more detail is clearToolItem, which is a function that clears tabs. There are two rules involved:
If the close is the currently active TAB, after the close. The active TAB is the last open TAB by default.
If the current TAB is the last one (active), it automatically defaults to the one before it as the default active TAB when it is closed.
import router from '.. /router'
exportDefault {state: {toolBarData:[],// Save an array of labels for buttons cacheView:[] // Save an array to cache}, getters: {getToolData(state){return state.toolBarData;
},
getCacheView(state){
return state.cacheView;
}
},
mutations: {
setToolData(state, data) {// Add the tag button, not to repeat const if the current route is already openinToolbar = state.toolBarData.find(item => item.detail === data.detail)
!inToolbar && state.toolBarData.push({ ... data }); },setCacheView (state, data) {/ /setToolData similarif(state.cacheView.includes(data.componentName))
return;
state.cacheView.push(data.componentName);
},
clearToolItem(state,detail){
const index = state.toolBarData.findIndex(item => item.detail === detail);
const isActive = router.app.$route.path == state.toolBarData[index]["detail"];
const len = state.toolBarData.length - 1;
state.toolBarData.splice(index,1);
(index == len || isActive) && router.push({path:state.toolBarData[state.toolBarData.length - 1]["detail"]});
},
clearCacheView(state,viewName){
const index = state.cacheView.findIndex(item => item == viewName);
state.cacheView.splice(index,1);
}
},
actions: {
commitToolBar({commit},data) {
commit("setToolData",data);
commit("setCacheView",data);
},
clearToolBar({commit},data){
commit("clearToolItem",data.detail);
},
clearCache({commit},data){
commit("clearCacheView",data); }}}Copy the code
Life cycle Activated and deactivated
If a routing component with a keep-alive cache is re-entered into the route, the routing component will not be re-created and therefore will not trigger the component’s lifecycle functions (e.g. BeforeCreate, Mounted, etc.). So update or clear the data on the page. Vue provides the activated and deActivated life cycle functions, activated when a route component is re-entered and deactivated when it leaves.
<template>
<div> A page</div>
</template>
<script>
export default {
data(){
return {
form :{
name:'',
password:''
}
}
},
activated(){
this.getList()
},
deactivated(){
Object.keys(this.form).map(key => {
this.form[key] = ''
})
}
}
</script>
Copy the code
Entry file cache route app.vue
In the app. vue entry file, use keep-alive to cache the matching route components, listen for the current route changes, and add cached routes and labels.
<template> <el-main style="position:relative; margin-top:45px;" > <! <div class="routeWrap"> <transition name=" favel-transform "> <keep-alive :include="cachedViews"> <router-view></router-view> </keep-alive> </transition> </div> </el-main> </template> <script> export default { watch: $route() {$route() {const componentName =this.$route. Matched [0]["components"]["default"]["name"]; const detail = this.$route.path; Const name = this.$route.meta[0]["name"]; this.$store.dispatch("commitToolBar", { name, detail, componentName }); } } } </script>Copy the code
conclusion
The above is the vuex + keep-Alive implementation TAB page cache problem, hope to help you, if you have any questions please throw a question.
Want to know about the VUex +keep-alive cache for mobile applications
add
If you don’t want it to cache, for example if you go to a new page – fill in the information – click ok and go straight back to the previous page, instead of going back to the previous page, the new page still exists. There are two ways to solve this problem, usually using the first one:
Methods a
/ / method
this.$store.dispatch('delVisitedViews'.this.$route);
this.$router.go(- 1);
or
this.$store.dispatch('delVisitedViews',
{ name:this.$route.name,
title:this.$route.meta.name,
path:this.$route.path}).then((a)= >{
this.$router.push({path:' '},
(route)=>{ this.route.isReflesh=true})})Copy the code
Method 2:
/ / method 2
this.$store.state.tagsView.visitedViews.splice(this.$store.state.tagsView.visitedViews.findIndex(item= >
item.path === this.$route.path), 1)
this.$router.push(this.$store.state.tagsView.visitedViews[this.$store.state.tagsView.visitedViews.length - 1].path)
Copy the code
Also give an example of embedded routines;
Route.js = route.js
{
path: ' '.component: Layout,
name: 'keyEvent'.alwaysShow: true.meta: { title: 'keyEvent'.icon: 'navmenu-business-setting' },
children: [{path: 'eventSearch'.component: (a)= >
import( '@/views/energy/keyEvents/eventSearch'),
name: 'eventSearch'.meta: {
title: 'eventSearch'.authCode: ['eap.keyEvent.eventSearch']}},]},Copy the code
EventSearch. Vue:
<script>
export default {
name:'eventSearch'. } </script>Copy the code
These two names are the key. If the name in router.js does not match the name in eventsearch.vue, it will not be cached.