Maison  >  Article  >  interface Web  >  Introduction à l'utilisation et aux principes des composants vue keep-alive

Introduction à l'utilisation et aux principes des composants vue keep-alive

不言
不言avant
2019-03-30 09:34:532649parcourir

Le contenu de cet article concerne l'utilisation et l'introduction des principes de vue keep-alive. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

keep-alive

keep-alive est un composant intégré de vue.js. Il peut enregistrer des instances de composants inactifs en mémoire au lieu de les détruire directement. ne seront pas rendus dans le DOM réel et n'apparaîtront pas non plus dans la chaîne de composants parent.
Il fournit deux attributs, exclure et inclure, permettant aux composants d'être mis en cache de manière conditionnelle.

L'utilisation du composant de commentaire ci-dessus

<keep-alive>
    <comment></comment>
</keep-alive>

sera mise en cache.

<keep-alive>
    <coma v-if="test"></coma>
    <comb v-else></comb>
</keep-alive>
<button @click="abc"></button>

export default{
    data(){
        reurn{
            test:true
        }
    },
    methods:{
        abc(){
            this.test=!this.test;
        }
    }
}

Lorsque vous cliquez sur le bouton, le composant coma et le composant peigne basculeront, mais à ce moment, l'état des deux composants sera mis en cache s'il y a une balise d'entrée dans a et b. composants, puis la valeur de la balise d'entrée ne change pas lors de sa commutation. Le composant

props

keep-alive fournit deux attributs, inclure et exclure, pour la mise en cache conditionnelle. Les deux peuvent être représentés par des chaînes séparées par des virgules, des expressions régulières ou des tableaux.

<keep-alive include="a">
    <component></component>
</keep-alive>
//name名为a的组件会被缓存起来

<keep-alive exclude="a">
    <component></component>
</keep-alive>
//name名为a的组件将不会被缓存。

Crochets de vie

keep-alive fournit deux crochets de vie, activés et désactivés.
Étant donné que keep-alive enregistrera le composant en mémoire et ne le détruira ni ne le reconstruira, il n'appellera pas les méthodes creted et autres du composant. Vous devez utiliser des hooks activés et désactivés pour déterminer si le composant est actif.

Implémentation approfondie du composant keep-alive

hooks créés et détruits
Le hook créé créera un objet de cache, qui est utilisé comme conteneur de cache pour enregistrer les nœuds Vnode.

created{
    this.cache=Object.create(null);
}

Le hook détruit efface toutes les instances de composant dans le cache lorsque le composant est détruit.

/* destroyed钩子中销毁所有cache中的组件实例 */
destroyed () {
    for (const key in this.cache) {
        pruneCacheEntry(this.cache[key])
    }
},

Vient ensuite la fonction de rendu.

render () {
    /* 得到slot插槽中的第一个组件 */
    const vnode: VNode = getFirstComponentChild(this.$slots.default)

    const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions
    if (componentOptions) {
        // check pattern
        /* 获取组件名称,优先获取组件的name字段,否则是组件的tag */
        const name: ?string = getComponentName(componentOptions)
        /* name不在inlcude中或者在exlude中则直接返回vnode(没有取缓存) */
        if (name && (
        (this.include && !matches(this.include, name)) ||
        (this.exclude && matches(this.exclude, name))
        )) {
            return vnode
        }
        const key: ?string = vnode.key == null
        // same constructor may get registered as different local components
        // so cid alone is not enough (#3269)
        ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
        : vnode.key
        /* 如果已经做过缓存了则直接从缓存中获取组件实例给vnode,还未缓存过则进行缓存 */
        if (this.cache[key]) {
            vnode.componentInstance = this.cache[key].componentInstance
        } else {
            this.cache[key] = vnode
        }
        /* keepAlive标记位 */
        vnode.data.keepAlive = true
    }
    return vnode
}

Récupérez d'abord le premier sous-composant via getFirstComponentChild et obtenez le nom du composant (si le nom du composant existe, utilisez directement le nom du composant, sinon la balise sera utilisée). Ensuite, le nom sera mis en correspondance via les attributs d'inclusion et d'exclusion. Si la correspondance échoue (indiquant que la mise en cache n'est pas requise), le vnode sera renvoyé directement sans aucune opération.

/* 检测name是否匹配 */
function matches (pattern: string | RegExp, name: string): boolean {
  if (typeof pattern === 'string') {
    /* 字符串情况,如a,b,c */
    return pattern.split(',').indexOf(name) > -1
  } else if (isRegExp(pattern)) {
    /* 正则 */
    return pattern.test(name)
  }
  /* istanbul ignore next */
  return false
}

La fonction permettant de détecter la correspondance des attributs d'inclusion et d'exclusion est très simple. Les attributs d'inclusion et d'exclusion prennent en charge des chaînes telles que "a,b,c" où les noms des composants sont séparés par des virgules et des expressions régulières. . matches utilise ces deux méthodes pour détecter s'il correspond au composant actuel.

if (this.cache[key]) {
    vnode.componentInstance = this.cache[key].componentInstance
} else {
    this.cache[key] = vnode
}

La chose suivante est très simple. Trouvez-le dans this.cache en fonction de la clé. S'il existe, cela signifie qu'il a déjà été mis en cache. Écrasez directement l'instance de composant (instance de composant) mise en cache. vnode au vnode actuel ci-dessus. Sinon, le vnode est stocké dans le cache.
Retournez enfin au vnode (lorsqu'il y a un cache, l'instance de composant du vnode a été remplacée par celle du cache).
Utilisez watch pour surveiller les modifications des propriétés pruneCache et pruneCache, et modifiez les données du cache dans le cache lorsqu'elles changent.

watch: {
    /* 监视include以及exclude,在被修改的时候对cache进行修正 */
    include (val: string | RegExp) {
        pruneCache(this.cache, this._vnode, name => matches(val, name))
    },
    exclude (val: string | RegExp) {
        pruneCache(this.cache, this._vnode, name => !matches(val, name))
    }
},

Jetons un coup d'œil à l'implémentation de pruneCache.

/* 修正cache */
function pruneCache (cache: VNodeCache, current: VNode, filter: Function) {
  for (const key in cache) {
    /* 取出cache中的vnode */
    const cachedNode: ?VNode = cache[key]
    if (cachedNode) {
      const name: ?string = getComponentName(cachedNode.componentOptions)
      /* name不符合filter条件的,同时不是目前渲染的vnode时,销毁vnode对应的组件实例(Vue实例),并从cache中移除 */
      if (name && !filter(name)) {
        if (cachedNode !== current) {
          pruneCacheEntry(cachedNode)
        }
        cache[key] = null
      }
    }
  }
} 

/* 销毁vnode对应的组件实例(Vue实例) */
function pruneCacheEntry (vnode: ?VNode) {
  if (vnode) {
    vnode.componentInstance.$destroy()
  }
}

Parcourez tous les éléments du cache S'ils ne répondent pas aux règles spécifiées par le filtre, pruneCacheEntry sera exécuté. pruneCacheEntry appellera la méthode $destroy de l'instance du composant pour détruire le composant.

Cet article est terminé ici. Pour un contenu plus passionnant, vous pouvez faire attention à la colonne Tutoriel vidéo JavaScript du site Web PHP chinois !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer