keep-alive组件

  在开发Vue项目时,大部分组件是没有必要多次渲染的,所以Vue提供了一个内置组件keep-alive来缓存组件内部状态,避免重复渲染

  文档:和<transition>相似,<keep-alive>是一个抽象组件:他自身不会渲染一个DOM元素,也不会出现在父组件链中

 

一、用法

  1、缓存动态组件

    <keep-alive>缓存动态组件时,会缓存不活动的组件实例,而不是销毁他们,此种方式并无太大的实用意义

      基本:

        <keep-alive>

          <component :is="view"></component>

        </keep-alive>

 

 

   2、缓存路由组件

      使用keep-alive可以将所有路径匹配到的路由组件都缓存起来,包括路由组件里的组件,这是使用最多的场景

      <keep-alive>

        <router-view></router-view>

      <keep-alive>

 

二、生命周期钩子

  再被keep-alive包含的组件/路由中,会多出两个生命周期的钩子:activated与deactivated

 

1、activated在组件第一次渲染时被调用,之后在每次缓存组件被激活时调用

  activated的调用时机:

    1、第一次进入缓存组件/路由,在mounted后面,beforeRouteEnter守卫传给next的回调函数之前调用

    beforeMount => 如果是从别的路由/组件进来的(组件销毁destroyed/或离开缓存deactivated) => mounted => activated 进入缓存组件 => 执行 beforeRouteEnter回调

 

      因为组件被缓存了,再次进入缓存路由/组件时,不会触发这些钩子

      //beforeCreate created beforeMount mounted 都不会触发

 

      所以之后的调用时机为:

       组件销毁destroyed/或离开缓存deactivated => activated进入当前缓存组件 => 执行beforeRouteEnter回调

       //组件缓存或者销毁,嵌套组件的销毁和缓存也在这里触发

2、deactivated:组件被停用(离开路由时)调用

    使用keep-alive就不会调用beforeDestroy(组件销毁前钩子)和destroyed(组件销毁),因为组件没有被销毁,而是被缓存起来了

    这个组件可以看做是beforeDestroy的替代,如果你缓存了组件,要在组件缓存的时候做一些事情,可以放在这个钩子里

 

     如果你离开了路由会依次触发:

      组件内的离开当前路由钩子 beforeRouteLeave => 路由前置守卫 beforeEach => 全局后置钩子 afterEach => deactivated离开缓存组件 => activated 进入缓存组件(进入的也是缓存组件)

      //如果离开的组件没有缓存的话 beforeDestroy会替换deactivated

      //如果进入的路由也没有缓存的话:全局后置钩子afterEach => destroyed 销毁 => beforeCreate等

 

三、缓存路由

  Vue2.1.0之前:

    1、配置一下路由元信息

    2、创建两个<keep-alive>标签

    3、使用v-if通过路由元信息判断缓存那些信息

      <keep-alive>

        <router-view v-if="$route.meta.keepAlive">这里是会被缓存的路由</router-view>

      </keep-alive>

 

  Vue2.1.0之后:

    Vue新增了两个属性配合keep-alive来有条件的缓存路由/组件

    新增属性:

          1、include:匹配的路由/组件,会被缓存

          2、exclude:匹配的路由/组件,不会被缓存

 

include和exclude支持三种方式来有条件的缓存路由:采用逗号分隔的字符串模式;正则形式;数组形式

 

1)缓存组件的方式

  正则和数组形式必须采用v-bind来使用:

    1、逗号分隔符

      <keep-alive include="a, b">

        <component :is="view"></component>

      </keep-alive>

    2、正则表达式

      <keep-alive :include="/a|b/">

        <component :is="view"></component>

      </keep-alive>

    3、数组

      <keep-alive :include="['a', 'b']">

        <component :is="view"></component>

      </keep-alive>

 

2)更多的时候我们用来缓存路由

  <keep-alive :include="/a|b/">

    <router-view></router-view>  

  </keep-alive>

 

匹配规则:

  1. 首先匹配组件的name选项,如果name选项不可用。
  2. 则匹配它的局部注册名称。 (父组件 components 选项的键值)
  3. 匿名组件,不可匹配

比如路由组件没有name选项,并且没有注册的组件名。

  1. 只能匹配当前被包裹的组件,不能匹配更下面嵌套的子组件

比如用在路由上,只能匹配路由组件的name选项,不能匹配路由组件里面的嵌套组件的name选项。

  1. 文档:<keep-alive>不会在函数式组件中正常工作,因为它们没有缓存实例。
  2. exclude的优先级大于include

也就是说:当includeexclude同时存在时,exclude生效,include不生效。

  <keep-alive include="a,b" exclude="a">
    <!--只有a不被缓存-->
    <router-view></router-view>
  </keep-alive>
复制代码

当组件被exclude匹配,该组件将不会被缓存,不会调用activateddeactivated


作者:OBKoro1
链接:https://juejin.im/post/5b41bdef6fb9a04fe63765f1
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
posted @ 2020-01-02 15:12  jbw123  阅读(250)  评论(0编辑  收藏  举报