Maison interface Web js tutoriel Résumé des points de connaissance de l'algorithme diff de vue

Résumé des points de connaissance de l'algorithme diff de vue

May 28, 2018 am 11:26 AM
diff 总结 知识点

Cet article partage avec vous un résumé des points de connaissances pertinents sur l'algorithme de comparaison de Vue. Les amis intéressés peuvent s'y référer.

Dom virtuel

L'algorithme de diff doit d'abord clarifier le concept selon lequel l'objet de diff est le dom virtuel, et la mise à jour du dom réel est le résultat de l'algorithme de diff

Classe de base Vnode

 constructor (
  。。。
 ) {
  this.tag = tag
  this.data = data
  this.children = children
  this.text = text
  this.elm = elm
  this.ns = undefined
  this.context = context
  this.fnContext = undefined
  this.fnOptions = undefined
  this.fnScopeId = undefined
  this.key = data && data.key
  this.componentOptions = componentOptions
  this.componentInstance = undefined
  this.parent = undefined
  this.raw = false
  this.isStatic = false
  this.isRootInsert = true
  this.isComment = false
  this.isCloned = false
  this.isOnce = false
  this.asyncFactory = asyncFactory
  this.asyncMeta = undefined
  this.isAsyncPlaceholder = false
 }
Copier après la connexion

Cette partie du code vise principalement à mieux comprendre la signification des attributs diff spécifiques dans l'algorithme diff, et bien sûr à mieux comprendre l'instance vnode

Le processus global

La fonction principale est la fonction patch

  • est un jugement Undef (que ce soit est indéfini ou nul)

  • // montage vide (probablement en tant que composant), créez un nouvel élément racinecreateElm(vnode, insertVnodeQueue) Ici vous pouvez constater que la création de nœuds n'est pas insérée un par un, mais mis dans une file d'attente pour un traitement par lots unifié

  • Fonction principale SameVnode

function sameVnode (a, b) {
 return (
  a.key === b.key && (
   (
    a.tag === b.tag &&
    a.isComment === b.isComment &&
    isDef(a.data) === isDef(b.data) &&
    sameInputType(a, b)
   ) || (
    isTrue(a.isAsyncPlaceholder) &&
    a.asyncFactory === b.asyncFactory &&
    isUndef(b.asyncFactory.error)
   )
  )
 )
}
Copier après la connexion

Voici une fonction de comparaison externe qui compare directement les clés et les balises de deux nœuds Comparaison des données (notez que les données font ici référence à VNodeData), en cas d'entrée, comparez directement le type.

export interface VNodeData {
 key?: string | number;
 slot?: string;
 scopedSlots?: { [key: string]: ScopedSlot };
 ref?: string;
 tag?: string;
 staticClass?: string;
 class?: any;
 staticStyle?: { [key: string]: any };
 style?: object[] | object;
 props?: { [key: string]: any };
 attrs?: { [key: string]: any };
 domProps?: { [key: string]: any };
 hook?: { [key: string]: Function };
 on?: { [key: string]: Function | Function[] };
 nativeOn?: { [key: string]: Function | Function[] };
 transition?: object;
 show?: boolean;
 inlineTemplate?: {
  render: Function;
  staticRenderFns: Function[];
 };
 directives?: VNodeDirective[];
 keepAlive?: boolean;
}
Copier après la connexion

Cela confirmera si les deux nœuds méritent une comparaison plus approfondie, sinon ils seront remplacés directement

Le processus de remplacement est principalement une fonction createElm et l'autre est la destruction de oldVNode

// destroy old node
    if (isDef(parentElm)) {
     removeVnodes(parentElm, [oldVnode], 0, 0)
    } else if (isDef(oldVnode.tag)) {
     invokeDestroyHook(oldVnode)
    }
Copier après la connexion

Le processus d'insertion consiste simplement à déterminer le type du nœud et à appeler

createComponent (il déterminera s'il y a des enfants puis l'appellera de manière récursive)

createComment

createTextNode

Utilisez la fonction d'insertion après la création

Après cela, vous devez utiliser la fonction hydrate pour mapper le dom virtuel et le dom réel

function insert (parent, elm, ref) {
  if (isDef(parent)) {
   if (isDef(ref)) {
    if (ref.parentNode === parent) {
     nodeOps.insertBefore(parent, elm, ref)
    }
   } else {
    nodeOps.appendChild(parent, elm)
   }
  }
 }
Copier après la connexion

Fonction principale

 function patchVnode (oldVnode, vnode, insertedVnodeQueue, removeOnly) {
  if (oldVnode === vnode) {
   return
  }

  const elm = vnode.elm = oldVnode.elm

  if (isTrue(oldVnode.isAsyncPlaceholder)) {
   if (isDef(vnode.asyncFactory.resolved)) {
    hydrate(oldVnode.elm, vnode, insertedVnodeQueue)
   } else {
    vnode.isAsyncPlaceholder = true
   }
   return
  }

  if (isTrue(vnode.isStatic) &&
   isTrue(oldVnode.isStatic) &&
   vnode.key === oldVnode.key &&
   (isTrue(vnode.isCloned) || isTrue(vnode.isOnce))
  ) {
   vnode.componentInstance = oldVnode.componentInstance
   return
  }

  let i
  const data = vnode.data
  if (isDef(data) && isDef(i = data.hook) && isDef(i = i.prepatch)) {
   i(oldVnode, vnode)
  }

  const oldCh = oldVnode.children
  const ch = vnode.children
  if (isDef(data) && isPatchable(vnode)) {
   for (i = 0; i < cbs.update.length; ++i) cbs.update[i](oldVnode, vnode)
   if (isDef(i = data.hook) && isDef(i = i.update)) i(oldVnode, vnode)
  }
  if (isUndef(vnode.text)) {
   if (isDef(oldCh) && isDef(ch)) {
    if (oldCh !== ch) updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly)
   } else if (isDef(ch)) {
    if (isDef(oldVnode.text)) nodeOps.setTextContent(elm, &#39;&#39;)
    addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue)
   } else if (isDef(oldCh)) {
    removeVnodes(elm, oldCh, 0, oldCh.length - 1)
   } else if (isDef(oldVnode.text)) {
    nodeOps.setTextContent(elm, &#39;&#39;)
   }
  } else if (oldVnode.text !== vnode.text) {
   nodeOps.setTextContent(elm, vnode.text)
  }
  if (isDef(data)) {
   if (isDef(i = data.hook) && isDef(i = i.postpatch)) i(oldVnode, vnode)
  }
 }
Copier après la connexion

const el = vnode.el = oldVnode.el C'est une étape très importante Laissons vnode.el faire référence au domaine réel actuel. el est modifié, vnode.el changera de manière synchrone.

  1. Comparez les deux références pour voir si elles sont cohérentes

  2. Je ne sais pas ce que fait asyncFactory après ça, donc je ne peux pas comprenez cela.

  3. Clé de comparaison de nœuds statiques, aucun nouveau rendu ne sera effectué après le même, copiez directement l'instance de composant (une fois que la commande prend effet ici)

  4. Si vnode est un nœud de texte ou un nœud de commentaire, mais lorsque vnode.text != oldVnode.text, il vous suffit de mettre à jour le contenu texte de vnode.elm

  5. Comparaison de enfants

  • Si seul oldVnode a des nœuds enfants, supprimez ces nœuds

  • Si seul vnode a des nœuds enfants, alors créez ces nœuds enfants. Ici, si oldVnode est Le nœud de texte définit le texte de vnode.elm sur la chaîne vide

  • , alors updateChildren sera mis à jour. Cela sera détaillé plus tard<🎜. >

  • Si oldVnode et vnode n'ont pas de nœuds enfants, mais que oldVnode est un nœud de texte ou un nœud de commentaire, définissez donc le texte de vnode.elm sur la chaîne vide

updateChildren

Cette partie se concentre toujours sur l'ensemble de l'algorithme

Quatre premiers pointeurs, oldStart, oldEnd, newStart, newEnd, deux tableaux, oldVnode, Nœud virtuel.

function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {
  let oldStartIdx = 0
  let newStartIdx = 0
  let oldEndIdx = oldCh.length - 1
  let oldStartVnode = oldCh[0]
  let oldEndVnode = oldCh[oldEndIdx]
  let newEndIdx = newCh.length - 1
  let newStartVnode = newCh[0]
  let newEndVnode = newCh[newEndIdx]
  let oldKeyToIdx, idxInOld, vnodeToMove, refElm

  while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
   if (isUndef(oldStartVnode)) {
    oldStartVnode = oldCh[++oldStartIdx] // Vnode has been moved left
   } else if (isUndef(oldEndVnode)) {
    oldEndVnode = oldCh[--oldEndIdx]
   } else if (sameVnode(oldStartVnode, newStartVnode)) {
    patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue)
    oldStartVnode = oldCh[++oldStartIdx]
    newStartVnode = newCh[++newStartIdx]
   } else if (sameVnode(oldEndVnode, newEndVnode)) {
    patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue)
    oldEndVnode = oldCh[--oldEndIdx]
    newEndVnode = newCh[--newEndIdx]
   } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right
    patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue)
    canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm))
    oldStartVnode = oldCh[++oldStartIdx]
    newEndVnode = newCh[--newEndIdx]
   } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left
    patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue)
    canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm)
    oldEndVnode = oldCh[--oldEndIdx]
    newStartVnode = newCh[++newStartIdx]
   } else {
    if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)
    idxInOld = isDef(newStartVnode.key)
     ? oldKeyToIdx[newStartVnode.key]
     : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx)
    if (isUndef(idxInOld)) { // New element
     createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)
    } else {
     vnodeToMove = oldCh[idxInOld]
     if (sameVnode(vnodeToMove, newStartVnode)) {
      patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue)
      oldCh[idxInOld] = undefined
      canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm)
     } else {
      // same key but different element. treat as new element
      createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)
     }
    }
    newStartVnode = newCh[++newStartIdx]
   }
  }
  if (oldStartIdx > oldEndIdx) {
   refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm
   addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue)
  } else if (newStartIdx > newEndIdx) {
   removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx)
  }
 }
Copier après la connexion
Plusieurs situations et traitement d'une comparaison de boucle (les ++ suivants -- font tous référence au ++ de l'index --) La comparaison est le nœud nœud comparé L'abréviation n'est pas rigoureuse et. la comparaison est utilisée La fonction sameVnode n'est pas vraiment congruente

La condition pour que la boucle entière ne se termine pas oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx

  1. oldStart === newStart, oldStart++ newEnd --

  2. oldEnd === newStart, oldEnd est inséré au début de la file d'attente oldEnd-- newStart++

  3. Toutes les situations restantes sont traitées de cette façon. Pour faire simple, il y a deux processus après traitement, newStart++

  4. newStart trouve le même dans old, puis. déplacez-le avant oldStart
  5. Si vous ne trouvez pas le même, créez-en un et placez-le avant oldStart
  • Il n'est pas terminé après la fin de la boucle

    Il y a encore une période de jugement avant qu'elle ne soit terminée
  • Pour faire simple, une fois la boucle terminée, regardez le contenu entre les quatre pointeurs In. l'ancien tableau et le nouveau tableau, plus est renvoyé et moins est ajouté.

  • Ce qui précède est ce que j'ai compilé pour vous, j'espère qu'il sera utile à tout le monde à l'avenir.

Articles associés :

Méthode Angular5 d'ajout de classes de style aux balises du composant lui-même
if (oldStartIdx > oldEndIdx) {
   refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm
   addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue)
  } else if (newStartIdx > newEndIdx) {
   removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx)
  }
Copier après la connexion

Environnement de développement vue-cli à implémenter Méthode de requêtes inter-domaines

Explication détaillée du problème de construction automatique du terminal mobile Vue-cli webpack

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 de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Collection d'aide-mémoire Python, quels points de connaissances maîtrisez-vous ? Collection d'aide-mémoire Python, quels points de connaissances maîtrisez-vous ? Apr 26, 2023 pm 10:49 PM

Python est actuellement le langage de programmation le plus populaire. Je pense qu'un grand nombre d'amis novices rejoindront les rangs de l'apprentissage chaque jour. Cependant, même si une langue est facile à apprendre, il existe encore de nombreux concepts et connaissances de base. Pour un novice, il est toujours difficile de maîtriser autant de choses à la fois. Aujourd'hui, j'ai rassemblé de nombreuses aide-mémoire sur les connaissances liées à Python, qui peuvent être considérées comme exhaustives. À l'avenir, maman n'aura plus à s'inquiéter du fait que tout le monde ne puisse se souvenir d'aucun point de connaissance ! Notions de base de Python Notions de base de Python Cette aide-mémoire contient toutes les connaissances de base de Python, des types de données variables aux chaînes de liste, de l'installation de l'environnement à l'utilisation des bibliothèques couramment utilisées, elle peut être considérée comme complète. Python pour débutants

Résumer l'utilisation de la fonction system() dans le système Linux Résumer l'utilisation de la fonction system() dans le système Linux Feb 23, 2024 pm 06:45 PM

Résumé de la fonction system() sous Linux Dans le système Linux, la fonction system() est une fonction très couramment utilisée, qui permet d'exécuter des commandes en ligne de commande. Cet article présentera la fonction system() en détail et fournira quelques exemples de code spécifiques. 1. Utilisation de base de la fonction system(). La déclaration de la fonction system() est la suivante : intsystem(constchar*command) où le paramètre de commande est un caractère.

Remplacer svn diff par vimdiff : un outil pour comparer le code Remplacer svn diff par vimdiff : un outil pour comparer le code Jan 09, 2024 pm 07:54 PM

Sous Linux, il est très difficile d'utiliser directement la commande svndiff pour visualiser les modifications de code, j'ai donc cherché une meilleure solution sur Internet, qui consiste à utiliser vimdiff comme outil de visualisation de code pour svndiff, en particulier pour les personnes habituées à utiliser vim. C'est très pratique. Lorsque vous utilisez la commande svndiff pour comparer les modifications d'un certain fichier, par exemple, si vous exécutez la commande suivante : $svndiff-r4420ngx_http_limit_req_module.c, la commande suivante sera en fait envoyée au programme diff par défaut : -u-Lngx_http_limit_req_module.c (révision4420)-Lngx_

Révéler les secrets du mécanisme de mise en cache HTML : points de connaissances essentiels Révéler les secrets du mécanisme de mise en cache HTML : points de connaissances essentiels Jan 23, 2024 am 08:51 AM

Le secret du mécanisme de mise en cache HTML : points de connaissances essentiels, des exemples de code spécifiques sont requis Dans le développement Web, les performances ont toujours été une considération importante. Le mécanisme de mise en cache HTML est l'une des clés pour améliorer les performances des pages Web. Cet article révélera les principes et les compétences pratiques du mécanisme de mise en cache HTML et fournira des exemples de code spécifiques. 1. Principe du mécanisme de mise en cache HTML Lors du processus d'accès à une page Web, le navigateur demande au serveur d'obtenir la page HTML via le protocole HTTP. Le mécanisme de mise en cache HTML consiste à mettre en cache les pages HTML dans le navigateur

Explication détaillée des types de données MySQL : ce que vous devez savoir Explication détaillée des types de données MySQL : ce que vous devez savoir Jun 15, 2023 am 08:56 AM

MySQL est l'un des systèmes de gestion de bases de données relationnelles les plus populaires au monde et est largement utilisé en raison de sa fiabilité, de sa haute sécurité, de sa grande évolutivité et de son coût relativement faible. Les types de données MySQL définissent les méthodes de stockage de différents types de données et constituent une partie importante de MySQL. Cet article expliquera en détail les types de données de MySQL et certains points de connaissances auxquels il faut prêter attention dans les applications pratiques. 1. Classification des types de données MySQL Les types de données MySQL peuvent être divisés dans les catégories suivantes : Types entiers : y compris TINYINT,

Introduction à la sécurité des réseaux : Quels sont les points de connaissances essentiels pour les débutants ? Introduction à la sécurité des réseaux : Quels sont les points de connaissances essentiels pour les débutants ? Jun 11, 2023 am 09:57 AM

Introduction à la sécurité des réseaux : Quels sont les points de connaissances essentiels pour les débutants ? Ces dernières années, avec le développement rapide d’Internet, la sécurité des réseaux a attiré de plus en plus d’attention. Cependant, pour de nombreuses personnes, la sécurité des réseaux reste encore un océan inconnu. Alors, pour se lancer dans la sécurité des réseaux, quelles connaissances essentielles les débutants doivent-ils maîtriser ? Cet article va régler le problème pour vous. 1. Attaques et menaces réseau Tout d'abord, comprendre les types d'attaques et de menaces réseau est un point de connaissance qui doit être maîtrisé pour se lancer dans la sécurité réseau. Il existe de nombreux types de cyberattaques telles que les attaques de phishing, les logiciels malveillants, les ransomwares.

Types de données Oracle révélés : points de connaissances que vous devez connaître Types de données Oracle révélés : points de connaissances que vous devez connaître Mar 07, 2024 pm 05:18 PM

Le secret des types de données Oracle : points de connaissances que vous devez comprendre et exemples de code spécifiques. En tant que l'un des principaux systèmes de gestion de bases de données au monde, Oracle joue un rôle important dans le stockage et le traitement des données. Dans Oracle, le type de données est un concept très important qui définit le format de stockage, la plage et la méthode de fonctionnement des données dans la base de données. Cet article révélera divers points de connaissance des types de données Oracle et démontrera leur utilisation et leurs caractéristiques à travers des exemples de code spécifiques. 1. Types de données courants types de données de caractères

Résumé de l'expérience de gestion des flux de travail Git Résumé de l'expérience de gestion des flux de travail Git Nov 03, 2023 pm 06:45 PM

Résumé de l'expérience de gestion de workflow Git Introduction : Dans le développement de logiciels, la gestion des versions est un maillon très important. En tant que l'un des outils de gestion de versions les plus populaires actuellement, les puissantes capacités de gestion de branches de Git rendent la collaboration en équipe plus efficace et plus flexible. Cet article résumera et partagera l'expérience de la gestion des workflows Git. 1. Introduction au workflow Git Git prend en charge une variété de workflows et vous pouvez choisir le workflow approprié en fonction de la situation réelle de l'équipe. Les workflows Git courants incluent le workflow centralisé, le workflow de branche de fonctionnalités, GitF

See all articles