Introduction to keep-alive
keep-alive is a built-in component of Vue that allows contained components to retain state or avoid re-rendering.
Usage is also very simple:
<keep-alive> <component> <!-- This component will be cached! --> </component> </keep-alive>
props
- include - string or regular expression, only matching components will be cached
- exclude - string or regular expression, any matching components will not be cached
// component a export default { name: 'a', data () { return {} } }
<keep-alive include="a"> <component> <!-- The component with name a will be cached! --> </component> </keep-alive> can keep its state or avoid re-rendering
<keep-alive exclude="a"> <component> <!-- All components except the name a will be cached! --> </component> </keep-alive> can keep its state or avoid re-rendering
<keep-alive include="test-keep-alive">
<!-- 将缓存name为test-keep-alive的组件 -->
<component></component>
</keep-alive>
<keep-alive include="a,b">
<!-- 将缓存name为a或者b的组件,结合动态组件使用 -->
<component :is="view"></component>
</keep-alive>
<!-- 使用正则表达式,需使用v-bind -->
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>
<!-- 动态判断 -->
<keep-alive :include="includedComponents">
<router-view></router-view>
</keep-alive>
<keep-alive exclude="test-keep-alive">
<!-- 将不缓存name为test-keep-alive的组件 -->
<component></component>
</keep-alive>
Meet vue-router
router-view is also a component. If it is directly wrapped in keep-alive, all view components matching the path will be cached:
<keep-alive> <router-view> <!-- All view components matching the path will be cached! --> </router-view> </keep-alive>
However, the product Wang always has to change the demand, and he can't stop it...
question
What if you only want a certain component in router-view to be cached?
- 使用 include/exclude
- Add router.meta property
使用 include/exclude
// component a export default { name: 'a', data () { return {} } }
<keep-alive include="a"> <router-view> <!-- Only the view a component whose path matches will be cached! --> </router-view> </keep-alive>
The exclude example is similar.
Disadvantages: Need to know the name of the component, not a good choice when the project is complex
Add router.meta property
// routes configuration export default [ { path: '/', name: 'home', component: Home, meta: { keepAlive: true // needs to be cached } }, { path: '/:id', name: 'edit', component: Edit, meta: { keepAlive: false // don't need to be cached } } ]
<keep-alive> <router-view v-if="$route.meta.keepAlive"> <!-- here is the view component that will be cached, like Home! --> </router-view> </keep-alive> <router-view v-if="!$route.meta.keepAlive"> <!-- Here are view components that are not cached, such as Edit! --> </router-view>
Advantage: No need to enumerate the name of the component that needs to be cached
[Add salt] Use router.meta to expand
Suppose there are 3 routes: A, B, C.
need:
- Displays A by default
- B jumps to A, A does not refresh
- C jumps to A, A refreshes
Method to realize
Set the meta attribute in the A route:
{ path: '/', name: 'A', component: A, meta: { keepAlive: true // needs to be cached } }
Set beforeRouteLeave in B component:
export default { data() { return {}; }, methods: {}, beforeRouteLeave(to, from, next) { // set the meta of the next route to.meta.keepAlive = true; // Let A cache, that is, not refresh next(); } };
Set beforeRouteLeave in the C component:
export default { data() { return {}; }, methods: {}, beforeRouteLeave(to, from, next) { // set the meta of the next route to.meta.keepAlive = false; // Let A not cache, that is, refresh next(); } };
In this way, it can be realized that B returns to A, A does not refresh; and C returns to A and refreshes.
Summarize
The routing method is good, you don't need to care which page jumps over, as long as router.go(-1) can go back, no additional parameters are required.
However, in non-single-page applications, keep-alive cannot be effectively cached = =