Error de Vuejs: el árbol DOM virtual renderizado del lado del cliente no coincide con el renderizado del servidor
Estoy usando Nuxt.js/Vuejs para mi aplicación y sigo enfrentando este error en diferentes lugares:
The client-side rendered virtual DOM tree is not matching server-rendered content.
This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>.
Bailing hydration and performing full client-side render.
Me gustaría saber cuál es la mejor manera de depurar este error. ¿Es una forma de registrar/obtener el árbol DOM virtual para el cliente y el servidor para poder comparar y encontrar dónde se encuentra el error?
La mía es una aplicación grande y la verificación manual es difícil.
Respuesta parcial: con Chrome DevTools, puedes localizar el problema y ver exactamente qué elemento lo causó. Haga lo siguiente (lo hice con Nuxt 5.6.0 y Chrome 64.0.3282.186)
- Mostrar DevTools en Chrome (F12)
- Cargue la página que causa la advertencia "el árbol DOM virtual renderizado del lado del cliente...".
- Desplácese hasta la advertencia en la consola de DevTools.
- Haga clic en el hipervínculo de la ubicación de origen de la advertencia (en mi caso fue vue.runtime.esm.js:574).
- Establezca un punto de interrupción allí (haciendo clic izquierdo en el número de línea en el navegador de código fuente).
- Haga que vuelva a aparecer la misma advertencia. No digo que siempre sea posible, pero en mi caso simplemente recargué la página. Si hay muchas advertencias, puede verificar el mensaje moviendo el mouse sobre
msg
la variable. - Cuando encontró su mensaje y se detuvo en un punto de interrupción, mire la pila de llamadas. Haga clic en un cuadro hacia abajo para llamar a "parchear" y abrir su código fuente. Pase el mouse sobre
hydrate
la llamada de función 4 líneas por encima de la línea de ejecución enpatch
.hydrate
Se abriría un hipervínculo a la fuente de . - En la
hydrate
función, mueva aproximadamente 15 líneas desde el inicio y establezca un punto de interrupción dondefalse
se devuelve después deassertNodeMatch
regresarfalse
. Establezca el punto de interrupción allí y elimine todos los demás puntos de interrupción. - Haga que la misma advertencia vuelva a suceder. Ahora, cuando se alcanza el punto de interrupción, la ejecución debería detenerse en la
hydrate
función. Cambie a la consola de DevTools y evalúeelm
y luegovnode
. Aquí elm parece ser un elemento DOM renderizado por el servidor, mientras que vnode es un nodo DOM virtual. Elm está impreso como HTML para que puedas averiguar dónde ocurrió el error.
Para mí, este error ocurrió porque obtuve la lista de matrices AsyncData
y <tr>
las etiquetas representadas v-for
, puse v-for
códigos en <client-only>
bloques y el problema se resolvió
Este error puede ser realmente doloroso de depurar. Para obtener rápidamente el elemento que causa el problema, edite node_modules/vue/dist/vue.esm.js
y agregue las siguientes líneas:
// Search for this line:
function hydrate (elm, vnode, insertedVnodeQueue, inVPre) {
var i;
var tag = vnode.tag;
var data = vnode.data;
var children = vnode.children;
inVPre = inVPre || (data && data.pre);
vnode.elm = elm;
// Add the following lines:
console.log('elm', elm)
console.log('vnode', vnode)
console.log('inVpre', inVPre)
// ...
Obtendrá en la consola el nodo defectuoso.