深入了解组件- -- 动态组件 & 异步组件

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> 不会在函数式组件中正常工作,因为它们没有缓存实例。

异步组件和处理加载状态暂不学习,牵涉到工厂函数。

原文地址:https://www.cnblogs.com/1156063074hp/p/10097804.html