Maison interface Web js tutoriel Code pratique du projet Vue+Sortable

Code pratique du projet Vue+Sortable

Jun 11, 2018 am 10:23 AM
vue

Cette fois, je vais vous apporter le code réel du projet Vue+Sortable. Quelles sont les précautions pour la mise en œuvre réelle du projet Vue+Sortable ? Ce qui suit est un cas pratique, jetons un coup d'oeil.

J'ai précédemment développé un système de gestion backend qui utilisait la bibliothèque de composants Vue et Element-UI. J'ai rencontré un problème très intéressant et j'aimerais le partager avec vous.

La scène est comme ceci. Sur une page d'affichage de liste, j'ai utilisé le composant table d'Element-UI. La nouvelle exigence est de prendre en charge le tri par glisser-déposer basé sur la table d'origine. Cependant, le composant d'origine lui-même ne prend pas en charge le tri par glisser-déposer, et comme il est directement introduit depuis Element-UI, il n'est pas pratique de modifier son code source, la seule méthode réalisable est donc d'exploiter directement le DOM.

La méthode spécifique consiste à effectuer de vraies opérations DOM sur this.$el dans la fonction de cycle de vie montée, à écouter une série d'événements de glisser, à déplacer le DOM dans le rappel d'événement et à mettre à jour les données.

Il existe de nombreux événements HTML5 Drag, qui sont similaires aux événements Touch. Vous pouvez également les implémenter manuellement, mais ici, je suis paresseux et j'utilise une bibliothèque open source Sortable et je la transmets directement.$el. Écoutez le rappel encapsulé et, selon le modèle de développement de Vue, mettez à jour les données de données réelles dans le rappel du DOM mobile pour maintenir la cohérence entre les données et le DOM.

Si vous pensez que c'est par ici, vous vous trompez totalement, tôt ou tard, vous devrez rembourser la paresse que vous avez volée. . . Je pensais que cette solution était très bonne, mais dès que j'ai voulu la déboguer, un phénomène étrange s'est produit : après que A et B aient été glissés et échangés, B et A ont été à nouveau échangés comme par magie ! Que se passe-t-il? Il semble qu'il n'y ait aucun problème avec notre opération.Une fois le vrai DOM déplacé, nous déplaçons également les données correspondantes.L'ordre du tableau de données et l'ordre du DOM rendu doivent être cohérents.

Quel est le problème ? Rappelons le principe d'implémentation de Vue. Avant Vue2.0, la liaison bidirectionnelle était réalisée via l'injection et le suivi des dépendances DefineProperty. Pour l'instruction de tableau v-for, si une clé unique est spécifiée, la différence des éléments du tableau sera calculée via un algorithme Diff efficace et des opérations de mouvement ou de suppression minimales seront effectuées. Après l'introduction de Virtual Dom après Vue 2.0, l'algorithme Dom Diff de l'élément Children est en fait similaire au premier. La seule différence est qu'avant 2.0, Diff ciblait directement l'objet tableau de l'instruction v-for, tandis qu'après 2.0, il ciblait le Virtual Dom. L'algorithme DOM Diff ne sera pas décrit en détail ici. L'algorithme de comparaison dom virtuel est expliqué plus clairement ici

Supposons que notre tableau d'éléments de liste soit

['A',' B', 'C', 'D']

Le nœud DOM rendu est

[$A,$B,$C,$D]

Alors la structure correspondante de Virtual Dom est

[{elm:$A,data:'A'},
{elm:$B,data:'B '} ,
{elm:$C,data:'C'},
{elm:$D,data:'D'}]

En supposant qu'après le glisser-déposer tri, le vrai Le DOM devient

[$B,$A,$C,$D]

A cette époque nous avons seulement manipulé le vrai DOM et adapté son position, et La structure de Virtual Dom n'a pas changé, elle est toujours

[{elm:$A,data:'A'},
{elm:$B,data:' B'},
{elm:$C,data:'C'},
{elm:$D,data:'D'}]

En ce moment, nous changer les éléments de la liste en fonction du vrai DOM Après le tri, cela devient

['B','A','C','D']

At cette fois, selon l'algorithme Diff, le Patch calculé est , les deux premiers éléments de VNode sont des nœuds du même type, ils sont donc mis à jour directement, c'est-à-dire que le nœud $A est mis à jour en $B, le nœud $B est mis à jour en $A, et le vrai DOM revient à

[ $A,$B,$C,$D]

Il y a donc un problème qui il est mis à jour par l'algorithme Patch après le glisser. Le chemin de l'opération peut être simplement compris comme

Glisser et déposer pour déplacer le vrai DOM -> Manipuler le tableau de données -> 🎜>

La cause profonde

La cause profonde se situe entre le DOM virtuel et le DOM réel. Il y a une incohérence.

Donc, avant Vue2.0, comme Virtual DOM n'a pas été introduit, ce problème n'existait pas.

Lorsque vous utilisez le framework Vue, essayez d'éviter de manipuler directement le DOM

Solution

1. Marquez de manière unique chaque VNode en définissant une clé. C'est également la manière dont Vue recommande d'utiliser l'instruction v-for. Parce que la méthode sameVnode sera appelée pour juger si deux VNodes sont du même type, la priorité est de juger si la clé est la même

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)
 )
}
Copier après la connexion

2. Parce que la raison fondamentale est que le vrai DOM et Les VNode sont incohérents, vous pouvez donc déplacer le vrai DOM en faisant glisser Le fonctionnement du DOM est restauré, c'est-à-dire que dans la fonction de rappel, [$B, $A, $C, $D] est restauré en [$A, $B , $C, $D], et l'opération du DOM est renvoyée à Vue

Faites glisser et déplacez le vrai DOM ->Restaurer l'opération de déplacement-> Manipuler le tableau de données-> le vrai DOM

Le code est le suivant

var app = new Vue({
    el: '#app', 
    mounted:function(){
      var $ul = this.$el.querySelector('#ul')
      var that = this
      new Sortable($ul, {
        onUpdate:function(event){
          var newIndex = event.newIndex,
            oldIndex = event.oldIndex
            $li = $ul.children[newIndex],
            $oldLi = $ul.children[oldIndex]
          // 先删除移动的节点
          $ul.removeChild($li)  
          // 再插入移动的节点到原有节点,还原了移动的操作
          if(newIndex > oldIndex) {
            $ul.insertBefore($li,$oldLi)
          } else {
            $ul.insertBefore($li,$oldLi.nextSibling)
          }
          // 更新items数组
          var item = that.items.splice(oldIndex,1)
          that.items.splice(newIndex,0,item[0])
          // 下一个tick就会走patch更新
        }
      })
    },
    data:function() {
      return {
        message: 'Hello Vue!',
        items:[{
          key:'1',
          name:'1'
        },{
          key:'2',
          name:'2'
        },{
          key:'3',
          name:'3'
        },{
          key:'4',
          name:'4'
        }]
      }
    },
    watch:{
      items:function(){
        console.log(this.items.map(item => item.name))
      }
    }
  })
Copier après la connexion

3. Résoudre la violence ! Sans mise à jour du correctif, effectuez un nouveau rendu directement via les paramètres v-if. Bien sûr, ce n'est pas recommandé de faire cela, mais je donne juste cette idée~

    mounted:function(){
      var $ul = this.$el.querySelector('#ul')
      var that = this
      var updateFunc = function(event){
        var newIndex = event.newIndex,
          oldIndex = event.oldIndex
        var item = that.items.splice(oldIndex,1)
        that.items.splice(newIndex,0,item[0])
        // 暴力重新渲染!
        that.reRender = false
        // 借助nextTick和v-if重新渲染
        that.$nextTick(function(){
          that.reRender = true
          that.$nextTick(function(){
            // 重新渲染之后,重新进行Sortable绑定
            new Sortable(that.$el.querySelector('#ul'), {
              onUpdate:updateFunc
            })
          })
        })
      }
      new Sortable($ul, {
        onUpdate:updateFunc
      })
    },
Copier après la connexion

Donc, lorsque nous utilisons habituellement le framework, nous devons également comprendre le principe de mise en œuvre du framework, sinon nous le ferons rencontrez des situations difficiles. Pas moyen de commencer ~

Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !

Lecture recommandée :

Quelles spécifications d'écriture de code JS ont été publiées par Google

Vue+Nuxt.js pour faire le rendu du serveur

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.

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)

Comment ajouter des fonctions aux boutons pour Vue Comment ajouter des fonctions aux boutons pour Vue Apr 08, 2025 am 08:51 AM

Vous pouvez ajouter une fonction au bouton VUE en liant le bouton dans le modèle HTML à une méthode. Définissez la logique de la fonction de méthode et d'écriture dans l'instance Vue.

Comment utiliser Bootstrap en Vue Comment utiliser Bootstrap en Vue Apr 07, 2025 pm 11:33 PM

L'utilisation de bootstrap dans vue.js est divisée en cinq étapes: installer bootstrap. Importer un bootstrap dans main.js. Utilisez le composant bootstrap directement dans le modèle. Facultatif: style personnalisé. Facultatif: utilisez des plug-ins.

Comment référencer le fichier JS avec Vue.js Comment référencer le fichier JS avec Vue.js Apr 07, 2025 pm 11:27 PM

Il existe trois façons de se référer aux fichiers JS dans Vue.js: spécifiez directement le chemin à l'aide du & lt; script & gt; étiqueter;; importation dynamique à l'aide du crochet de cycle de vie monté (); et l'importation via la bibliothèque de gestion de l'État Vuex.

Comment utiliser Watch in Vue Comment utiliser Watch in Vue Apr 07, 2025 pm 11:36 PM

L'option Watch dans Vue.js permet aux développeurs d'écouter des modifications de données spécifiques. Lorsque les données changent, regardez déclenche une fonction de rappel pour effectuer des vues de mise à jour ou d'autres tâches. Ses options de configuration incluent immédiatement, qui spécifie s'il faut exécuter un rappel immédiatement, et profond, ce qui spécifie s'il faut écouter récursivement les modifications des objets ou des tableaux.

Que signifie le développement de plusieurs pages Vue? Que signifie le développement de plusieurs pages Vue? Apr 07, 2025 pm 11:57 PM

Le développement multi-pages VUE est un moyen de créer des applications à l'aide du cadre Vue.js, où l'application est divisée en pages distinctes: Maintenance du code: La division de l'application en plusieurs pages peut rendre le code plus facile à gérer et à maintenir. Modularité: chaque page peut être utilisée comme module séparé pour une réutilisation et un remplacement faciles. Routage simple: la navigation entre les pages peut être gérée par une configuration de routage simple. Optimisation du référencement: chaque page a sa propre URL, ce qui aide le référencement.

Comment revenir à la page précédente par Vue Comment revenir à la page précédente par Vue Apr 07, 2025 pm 11:30 PM

Vue.js dispose de quatre méthodes pour revenir à la page précédente: $ router.go (-1) $ router.back () utilise & lt; router-link to = & quot; / & quot; Composant Window.History.back (), et la sélection de la méthode dépend de la scène.

Comment interroger la version de Vue Comment interroger la version de Vue Apr 07, 2025 pm 11:24 PM

Vous pouvez interroger la version Vue en utilisant Vue Devtools pour afficher l'onglet Vue dans la console du navigateur. Utilisez NPM pour exécuter la commande "NPM List -g Vue". Recherchez l'élément VUE dans l'objet "dépendances" du fichier package.json. Pour les projets Vue CLI, exécutez la commande "Vue --version". Vérifiez les informations de la version dans le & lt; script & gt; Tag dans le fichier html qui fait référence au fichier VUE.

Comment utiliser la fonction interception vue Comment utiliser la fonction interception vue Apr 08, 2025 am 06:51 AM

L'interception de la fonction dans Vue est une technique utilisée pour limiter le nombre de fois qu'une fonction est appelée dans une période de temps spécifiée et prévenir les problèmes de performance. La méthode d'implémentation est: Importer la bibliothèque Lodash: import {Debounce} de 'Lodash'; Utilisez la fonction Debounce pour créer une fonction d'interception: const debouncedFunction = Debounce (() = & gt; {/ logical /}, 500); Appelez la fonction d'interception et la fonction de contrôle est appelée au plus une fois en 500 millisecondes.

See all articles