Hydration completed but contains mismatches 报错,如何解决?
最近在用vue3+node+TS+vite在搭建SSR服务器端渲染项目时候,遇到问题 Hydration completed but contains mismatches?字面意思就是客户端激活已完成,但是存在不匹配;若是第一次遇到这个问题,貌似还不是很懂?
所谓客户端激活指的是Vue在浏览器端接管由服务器发送的静态HTML,将其变为由Vue管理的动态DOM的过程,激活过后就可以进行点击事件等交互操作。
由于服务器已经渲染好了HTML,这样无需将其丢弃再重新创建所有的DOM元素,相反只需要"激活"这些静态的HTML。
激活的过程中Vue将检查客户端生成的虚拟DOM树(virtual DOM tree),是否与服务器渲染的DOM结构匹配;比如当你再Vue模板写入
<table> <tr><td>hello</td></tr> </table>
浏览器会在<table> 内部自动注入 <tbody>,然而Vue生成的虚拟DOM不包含<tbody>,这样就会导致不匹配出现上面的错误。
这样当SSR项目遇到Hydration completed but contains mismatches这样的错误时候,解决客户端生成的虚拟DOM树与服务器渲染好的静态HTML结构一致就行。
快速解决办法:结合上面的例子在客户端挂载时条件式地渲染,由于onMounted钩子函数在服务器端不执行,这样激活前客户端生成的虚拟DOM树与服务器渲染好的静态HTML结构都不包含table元素,因此能够匹配成功
<template> <table v-if="isClient"> <tr><td>hello</td></tr> </table> </template> <script setup> import { ref } from 'vue' const isClient = ref(false) onMounted(() => { isClient.value = true }) </script>
导致此种问题常见情况总结:
不规范DOM结构:https://cn.vuejs.org/guide/scaling-up/ssr.html#hydration-mismatch
Teleports组件:https://cn.vuejs.org/guide/scaling-up/ssr.html#teleports