Vue SSR场景下实现<server-only>效果避免hydration不匹配问题
Vue SSR 仅服务端渲染元素的合规实现方案
方案1:使用Vue官方内置组件(Vue 3.2及以上版本适用)
Vue 3.2+ 已经原生内置了 <ServerOnly> 组件,就是为了满足仅在服务端渲染内容的需求,完全符合框架规则,不会触发服务端客户端HTML不匹配报错,也不会导致额外的客户端重渲染。
使用方式如下:
<ServerOnly> <div class="h-nonav bg-gray-500" /> </ServerOnly>
客户端hydrate阶段会直接跳过该组件内部内容的比对,不会产生任何警告,也不需要额外写业务逻辑控制。
方案2:自定义ServerOnly组件(兼容低版本Vue/老项目)
如果你的项目使用的是低于3.2的Vue3版本、或者Vue2版本,可以自己封装一个通用的ServerOnly组件,实现逻辑符合Vue SSR的渲染规则:
- 新建
ServerOnly.vue组件:
<script> export default { render(h) { // 服务端渲染时输出插槽内容 if (process.server) { return this.$slots.default?.() || h() } // 客户端渲染时直接输出空节点 return h() } } </script>
- 业务代码中直接引入使用即可,和内置组件用法一致:
<ServerOnly> <div class="h-nonav bg-gray-500" /> </ServerOnly>
如果使用Vue3自定义组件时出现hydrate警告,可以给组件内部的根元素加上suppressHydrationWarning属性关闭警告即可。
你之前尝试的两种方案问题原因:
- 直接用
$isServer判断的写法,服务端渲染输出了对应div,客户端hydrate时$isServer为false,两端渲染结果不一致才会抛出不匹配错误- 用响应式变量在mounted中修改的写法,会因为修改响应式状态触发客户端额外重渲染,确实存在不必要的性能开销
内容的提问来源于stack exchange,提问作者Drdilyor
相关产品推荐
相关产品推荐

