Red de conocimiento informático - Problemas con los teléfonos móviles - Usando Ordenable en Vue

Usando Ordenable en Vue

He estado desarrollando un sistema de administración backend usando Vue y la biblioteca de componentes Element-UI, y me encontré con un problema interesante que quería compartir con ustedes.

El escenario es el siguiente: en la página de visualización de la lista, uso el componente de tabla de Element-UI y el nuevo requisito es admitir la clasificación mediante arrastrar y soltar en la parte superior de la tabla original. Sin embargo, el componente original en sí no admite la clasificación de arrastrar y soltar y, dado que es un componente introducido directamente en Element-UI, no es fácil modificar su código fuente, por lo que un método más factible es manipular directamente el DOM. .

El método específico es montar la función de ciclo de vida. This.$el en realidad realiza operaciones DOM, escucha una serie de eventos de arrastre, mueve el DOM en la devolución de llamada del evento y actualiza los datos.

Hay bastantes eventos de Arrastre en HTML5, que son similares a los eventos de Toque. También puedes implementarlos manualmente, pero aquí soy un vago. Fui vago y usé la biblioteca Sortable de código abierto para pasar this.$el, escuchar la devolución de llamada encapsulada y actualizar los datos reales en la devolución de llamada que mueve el DOM de acuerdo con el modelo de desarrollo de Vue para mantener los datos consistentes con el DOM.

Si crees que la historia termina aquí, estás equivocado. Pensé que esta escena era maravillosa, pero no esperaba que solo quisiera depurarla, y sucedió algo extraño: después de que A y B fueron arrastrados y soltados para intercambiar posiciones, ¡B y A volvieron a intercambiarse mágicamente! ¿Qué diablos está pasando? Parece que no hay ningún problema con nuestra operación. Después de mover el DOM real, también movimos los datos correspondientes, y el orden de la matriz de datos debe ser coherente con el orden en que se representan desde el DOM.

¿Cuál es el problema? Repasemos cómo Vue implementa esto. Antes de Vue 2.0, el enlace bidireccional se implementaba mediante la inyección y el seguimiento de dependencias defineProperty. Para la instrucción de matriz v-for, si se especifica una clave única, la diferencia de elementos en la matriz se calcula mediante un algoritmo Diff eficiente para realizar operaciones mínimas de movimiento o eliminación. Después de la introducción de Virtual Dom en Vue 2.0, el algoritmo Dom Diff para elementos infantiles es en realidad similar al algoritmo anterior. La única diferencia es que antes de 2.0, Diff apunta directamente al objeto de matriz de la instrucción v-for, mientras que después de 2.0, se dirige a Virtual Dom. El algoritmo DOM Diff no se describirá en detalle aquí, pero se explicará aquí

Supongamos que tenemos una matriz de elementos de lista

y el nodo DOM representado es

, entonces la estructura DOM virtual es

Supongamos que después de arrastrar y ordenar, el DOM real se convierte en

En este momento, simplemente operamos el DOM real y ajustamos su posición. , y luego podemos usar el DOM virtual para emparejar la lista. Los elementos están ordenados.

En este momento, también ordenamos los elementos de la lista según el DOM real.

En este momento, según el algoritmo Diff, el resultado del cálculo de Patch es VNode. dos son nodos del mismo tipo, por lo que actualice VNode directamente, es decir, actualice el nodo $A al nodo $A.

Por lo tanto, antes de Vue 2.0, dado que no se introdujo el DOM virtual, este problema no existía.

Cuando uses el framework Vue, debes intentar evitar manipular directamente el DOM

3. En lugar de realizar una actualización del parche, configúrelo mediante v-if y luego renderice nuevamente. Por supuesto, este no es un método recomendado, solo proporciona esta idea ~

Entonces, cuando usualmente usamos el marco, también debemos comprender el principio de implementación del marco; de lo contrario, estaremos indefensos cuando nos encontremos. algunas situaciones difíciles. ~