gitHub地址:https://github.com/huangpna/vue_learn/example里面的lesson11
一 在动态组件上使用keep-alive
在这之前我们已经有学习过用is特性来切换多标签的页面,但有些时候会想保持这些组件的状态,以避免反复重新渲染导致的性能问题。
举例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index1</title> <style> div,li,ul,p{ margin:0; padding:0; } li{ list-style:none; } #app1{ overflow: hidden; } #app1>div>ul{ float:left; } #app1>div>ul>li{ 80px; height:100px; line-height:100px; cursor: pointer; text-align:center; } #app1>div>ul>li:first-child{ background-color: #ff4225; } #app1>div>ul>li:last-child{ background-color: royalblue; } #app1>div>div{ border:1px solid red; 200px; height:200px; float:left; } #app1>div{ 800px; margin:0 auto; } #app1>div>div>div{ font-size:16px; text-align:center; line-height:200px; color:red; } </style> </head> <body> <div id="app1"> <div> <ul> <li v-for="(item,index) in navs" :key="index" @click="tab(item)">{{item}}</li> </ul> <div> <keep-alive> <component :is="currentTabComponent"></component> </keep-alive> </div> </div> </div> </body> <script src="../js/vue.js"></script> <script> var myHome = { template:'<div>include: 字符串或正则表达式。只有匹配的组件会被缓存。</div>' }; var myPosts = { template:'<div><label>输入框:</label><input type="text"/></div>' }; new Vue({ el:'#app1', data:{ currentTab:'Home', navs:['Home','Posts'] }, components:{ 'my-home':myHome, 'my-posts':myPosts }, methods:{ tab:function (v) { let _this = this; _this.currentTab = v; } }, computed:{ currentTabComponent:function () { let _this = this; return 'my-'+ _this.currentTab.toLowerCase(); } } }) </script> </html>
实现效果如下:
你会注意到,上述例子在未使用<keep-alive>之前,如果你点击了Posts导航标签,这个时候您在输入框内输入内容;切换到Home标签,然后再切换到回Posts,是不会继续展示你之前输入框内输入的内容的,这是因为你每次切换新标签的时候,Vue 都创建了一个新的 currentTabComponent
实例。为了解决这个问题,我们可以用一个<keep-alive>将其动态组件包裹起来,这边便能保持它的状态,让其在第一次被创建的时候缓存下来。
二 更多keep-alive细节深究
注意<keep-alive>要求被切换到的组件都有自己的名字,不论是通过组件的name选项还是局部。全局注册。
<keep-alive>作用于主要是包裹动态组件时,会缓存不活动的组件实例,而不是销毁他们。和<transition>相似,<keep-alive>是一个抽象组件:它自身不会渲染一个DOM元素,也不会出现在父组件链中。
Props:
include
- 字符串或正则表达式。只有名称匹配的组件会被缓存。exclude
- 字符串或正则表达式。任何名称匹配的组件都不会被缓存。max
- 数字。最多可以缓存多少组件实例。
用法:
include and exclude(2.1.0新增):
include
和 exclude
属性允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示:
例子:
<!-- 逗号分隔字符串 --> <keep-alive include="a,b"> <component :is="view"></component> </keep-alive> <!-- 正则表达式 (使用 `v-bind`) --> <keep-alive :include="/a|b/"> <component :is="view"></component> </keep-alive> <!-- 数组 (使用 `v-bind`) --> <keep-alive :include="['a', 'b']"> <component :is="view"></component> </keep-alive>
匹配首先检查组件自身的 name
选项,如果 name
选项不可用,则匹配它的局部注册名称 (父组件 components
选项的键值)。匿名组件不能被匹配。
max(2.5.0新增):
最多可以缓存多少组件实例。一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。
例子:
<keep-alive :max="10"> <component :is="view"></component> </keep-alive>
<keep-alive>
不会在函数式组件中正常工作,因为它们没有缓存实例。
异步组件和处理加载状态暂不学习,牵涉到工厂函数。