vue的keep-alive组件的使用及其实现原理

vue的keep-alive组件的使用及其实现原理,第1张

keep-alive是Vuejs的一个内置组件。它能够把不活动的组件实例保存在内存中,而不是直接将其销毁,它是一个抽象组件,不会被渲染到真实DOM中,也不会出现在父组件链中。

它提供了include与exclude两个属性,允许组件有条件地进行缓存

具体内容可以参考 官网 。

用法

这里的component组件会被缓存起来。

举个栗子

在点击button时候,coma与comb两个组件会发生切换,但是这时候这两个组件的状态会被缓存起来,比如说coma与comb组件中都有一个input标签,那么input标签中的内容不会因为组件的切换而消失。

props

keep-alive组件提供了include与exclude两个属性来允许组件有条件地进行缓存,二者都可以用逗号分隔字符串、正则表达式或一个数组来表示。

将缓存name为a的组件。

name为a的组件将不会被缓存。

生命钩子

keep-alive提供了两个生命钩子,分别是activated与deactivated。

因为keep-alive会将组件保存在内存中,并不会销毁以及重新创建,所以不会重新调用组件的created等方法,需要用activated与deactivated这两个生命钩子来得知当前组件是否处于活动状态。

说完了keep-alive组件的使用,我们从源码角度看一下keep-alive组件究竟是如何实现组件的缓存的呢?

created与destroyed钩子

created钩子会创建一个cache对象,用来作为缓存容器,保存vnode节点。

destroyed钩子则在组件被销毁的时候清除cache缓存中的所有组件实例。

render

首先通过getFirstComponentChild获取第一个子组件,获取该组件的name(存在组件名则直接使用组件名,否则会使用tag)。接下来会将这个name通过include与exclude属性进行匹配,匹配不成功(说明不需要进行缓存)则不进行任何 *** 作直接返回vnode,vnode是一个VNode类型的对象,不了解VNode的同学可以参考笔者的另一篇文章 《VNode节点》

检测include与exclude属性匹配的函数很简单,include与exclude属性支持字符串如"a,b,c"这样组件名以逗号隔开的情况以及正则表达式。matches通过这两种方式分别检测是否匹配当前组件。

接下来的事情很简单,根据key在thiscache中查找,如果存在则说明之前已经缓存过了,直接将缓存的vnode的componentInstance(组件实例)覆盖到目前的vnode上面。否则将vnode存储在cache中。

最后返回vnode(有缓存时该vnode的componentInstance已经被替换成缓存中的了)。

watch

用watch来监听include与exclude这两个属性的改变,在改变的时候修改cache缓存中的缓存数据。

来看一下pruneCache的实现。

遍历cache中的所有项,如果不符合filter指定的规则的话,则会执行pruneCacheEntry。pruneCacheEntry则会调用组件实例的$destroy方法来将组件销毁。

Vuejs内部将DOM节点抽象成了一个个的 VNode节点 , keep-alive组件的缓存也是基于VNode节点的而不是直接存储DOM结构。它将满足条件(include与exclude)的组件在cache对象中缓存起来,在需要重新渲染的时候再将vnode节点从cache对象中取出并渲染。

原文: 聊聊keep-alive组件的使用及其实现原理

1父组件向子组件传递数据

(1)$parent方法,在子组件中可以直接访问该组件的父实例或组件。

(2)$root方法,获取根组件对象。

2子组件向父组件传递数据

$children:返回的是所有子组件对象的数组,再通过下标获取指定的子组件。当组件顺序不会发生变化时,用 $children;否则用 $refs。 注意 :$refs:返回的是一个对象,对象中包含所有带有ref属性的子组件。 注意:不是只有组件才可以添加ref属性,任何标签都可以加ref属性 。

注意 :在父组件创建完成到挂载完成之间,包含完整的子组件的生命周期。父级组件在mounted生命周期函数内,才能获取到$children信息;在子组件的created生命周期函数中,可以获取到父组件的数据。顺序:父级created => 子级1created => 子级2created => => 子级1mounted => 子级2mounted => 父级mounted

常用的PC端组件库有: element-ui 、 iView 、 ant-design vue

常用的移动端组件库: Vant 、 Mint-ui

注意 :第三方组件库,必须在Vue的下面引入

效果:

注意 :非 template/render 模式下,一些组件名在实际使用中需使用 i-小写组件名 格式(例如 Button组件 需使用 i-button);一些组件标签名需要改成小写(例如 Tabs组件 需使用 tabs )。具体情况参考官网提示。

效果:

效果:

 //进入守卫:通过路由规则,进入该组件时被调用

   beforeRouteEnter (to, from, next) {

        // 在渲染该组件的对应路由被 confirm 前调用

    // 不!能!获取组件实例 `this`

    // 因为当守卫执行前,组件实例还没被创建

   },

  beforeRouteUpdate (to, from, next) {

      // 在这里面拿this$route拿的是修改前一次的数据

  // just use `this`

  thisname = toparamsname

  // 在当前路由改变,但是该组件被复用时调用

    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,

    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。

    // 可以访问组件实例 `this`

  next()

},

------------------------------------------------

不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。

beforeRouteEnter (to, from, next) {

  next(vm => {

    // 通过 `vm` 访问组件实例

  })

}

---------------------------------------------------

   //离开守卫:通过路由规则,离开该组件时被调用

   beforeRouteLeave (to, from, next) {

    // 导航离开该组件的对应路由时调用

    // 可以访问组件实例 `this`

   }

以上就是关于vue的keep-alive组件的使用及其实现原理全部的内容,包括:vue的keep-alive组件的使用及其实现原理、VUE从入门到入坑—06. 父子组件通信 / 几种常用的第三方组件库、vue局部路由守卫等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/10136292.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-05
下一篇2023-05-05

发表评论

登录后才能评论

评论列表(0条)

    保存