vue.js ssr 默认禁用响应式是性能优化设计,因服务端只需一次性渲染html,无需依赖收集和watcher;仅beforecreate/created和setup顶层执行,ref/reactive在ssr中为普通对象,须工厂函数创建独立store以避免状态污染。

Vue.js 的响应式数据在 SSR 环境下默认被禁用,这不是 bug,而是有意为之的性能优化设计。
为什么 SSR 中不启用响应式?
服务端渲染是一次性过程:组件接收初始数据,生成 HTML 字符串,然后响应结束。没有用户交互、没有 DOM 变更、也没有后续更新需求。启用响应式会带来额外开销——比如把普通对象转为 Proxy 或 defineReactive 对象,触发依赖收集、建立 watcher 链等,这些在服务端毫无意义。
- 避免不必要的内存分配和对象劫持
- 减少序列化前的数据处理时间
- 防止因响应式代理导致 context 或 store 数据意外被修改
哪些代码会在 SSR 中执行?哪些不会?
只有 beforeCreate 和 created 钩子会在服务端调用;mounted、updated、beforeUnmount 等仅客户端钩子完全跳过。setup() 或 <script setup> 的顶层语句也会执行,但需注意副作用边界。</script>
- ✅ 安全:在 created 中发起 API 请求、初始化非响应式状态(如 ref({}) 或 reactive({}) 的原始值)
- ❌ 危险:在 created 中启动 setInterval、监听 window.resize、直接操作 document.body
- ⚠️ 注意:使用 ref / reactive 创建的数据,在 SSR 中仍是普通 JS 对象,不会被转换为响应式代理
如何安全地共享状态?
SSR 要求“每个请求独享状态”,否则多个并发请求可能污染彼此的数据。推荐做法是:每次请求都创建全新 store 实例,并通过 context 注入组件树。
- 用工厂函数创建 store(如 createStore()),而非单例模式
- 将 store.state 序列化进页面 HTML 的 <script> 标签中(如 window.__INITIAL_STATE__)</script>
- 客户端激活时,用该初始状态重建 store,保证 hydration 一致性
需要响应式?可以手动开启(不推荐)
极少数场景(如服务端做复杂状态推导、或与 SSR 流式渲染深度耦合)可能需临时启用响应式,可通过 createSSRApp 的配置项或手动调用 reactive(),但必须确保:
- 不产生副作用(无定时器、无事件监听)
- 不访问浏览器专属 API(window、document)
- 最终输出的是纯 JSON 可序列化的 plain object
多数情况下,直接使用普通对象 + 解构赋值 + 渲染函数更轻量、更可控。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










