服务端渲染API变化
服务端渲染API变化
Vue.js 的服务端渲染(SSR)在版本迭代中经历了多次API调整,核心逻辑从vue-server-renderer
迁移到@vue/server-renderer
,底层实现机制也发生了显著变化。这些改动直接影响着同构应用的生命周期处理、状态管理以及渲染管道的配置方式。
渲染器创建方式重构
早期版本通过createRenderer
工厂函数生成渲染器实例:
const { createRenderer } = require('vue-server-renderer')
const renderer = createRenderer({
template: '<div id="app">{{ html }}</div>'
})
Vue 3 改为使用ES模块导出的独立函数:
import { renderToString } from '@vue/server-renderer'
const html = await renderToString(app)
主要变更点包括:
- 移除
bundleRenderer
概念,改为直接渲染Vue应用实例 - 模板系统改为通过
createSSRApp
的根组件控制 - 异步渲染默认返回Promise,需配合
async/await
使用
生命周期钩子调整
服务端特有的生命周期钩子从serverPrefetch
更名为onServerPrefetch
,并采用Composition API风格:
<script setup>
import { ref, onServerPrefetch } from 'vue'
const data = ref(null)
onServerPrefetch(async () => {
data.value = await fetchData()
})
</script>
废弃的beforeCreate
和created
钩子在SSR环境下不再被调用,初始化逻辑应迁移到setup()
或<script setup>
中。
状态序列化机制变化
Vue 2使用context.renderState
自动序列化状态:
context.renderState = { user: { name: 'Alice' } }
Vue 3改为显式使用useSSRContext
组合式函数:
<script setup>
import { useSSRContext } from 'vue'
const ctx = useSSRContext()
ctx.user = { name: 'Alice' }
</script>
客户端注水过程也相应调整为:
const app = createSSRApp(App)
if (typeof window !== 'undefined') {
const initialState = JSON.parse(window.__INITIAL_STATE__)
// 手动恢复状态
}
异步组件处理改进
新版SSR对动态导入的组件提供更精细的控制:
defineAsyncComponent({
loader: () => import('./Component.vue'),
serverLoader: () => require('./Component.vue') // 专为SSR提供的加载器
})
关键改进包括:
- 服务端和客户端可分别指定加载逻辑
- 支持
Suspense
组件在SSR环境下的降级处理 - 错误边界机制与SSR兼容性增强
流式渲染API升级
流式渲染接口从renderToStream
变更为renderToNodeStream
:
// Vue 2
renderer.renderToStream(context)
// Vue 3
const stream = renderToNodeStream(app)
stream.pipe(res)
新增renderToWebStream
支持Web Streams API:
const readable = renderToWebStream(app)
for await (const chunk of readable) {
// 处理分块内容
}
白名单与黑名单配置
客户端敏感指令的过滤方式从字符串匹配改为正则表达式:
// 旧版
renderer.directives = {
show: true // 白名单
}
// 新版
const { compile } = require('@vue/compiler-ssr')
compile(template, {
directiveTransforms: {
'my-dir': () => ({ props: [] }) // 自定义指令转换
}
})
性能追踪API变更
性能分析从context.rendered
回调改为独立API:
const { renderToString, performanceMark } = require('@vue/server-renderer')
performanceMark('renderStart')
const html = await renderToString(app)
performanceMark('renderEnd')
新增的指标包括:
- 组件实例化耗时
- 虚拟DOM生成时间
- HTML序列化延迟
错误处理策略优化
错误捕获机制从全局errorHandler
改为渲染上下文传递:
try {
await renderToString(app, {
onError(err) {
// 专属错误处理
}
})
} catch (e) {
// 顶层捕获
}
新增的错误类型包括:
- 组件级SSR异常(错误代码
SSR_COMPONENT_ERROR
) - 异步数据加载超时(错误代码
SSR_FETCH_TIMEOUT
) - 客户端注水不匹配警告(错误代码
HYDRATE_MISMATCH
)
自定义指令处理
SSR环境下的指令转换需要显式声明:
const app = createSSRApp({
directives: {
focus: {
mounted(el) { /* 客户端实现 */ },
ssrRender(props, vnode) {
// 服务端模拟逻辑
return { class: 'focused' }
}
}
}
})
未实现ssrRender
的指令会在服务端被静默忽略。
编译时配置调整
vue-loader
的SSR相关配置迁移到编译器选项:
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.tap(options => ({
...options,
compilerOptions: {
whitespace: 'condense',
directiveTransforms: true // 启用指令转换
}
}))
}
}
混合渲染模式支持
新增renderToSimpleStream
用于混合渲染场景:
const { renderToSimpleStream } = require('@vue/server-renderer')
// 首屏SSR + 后续CSR
const stream = renderToSimpleStream(app, {
push(chunk) {
// 分块发送
},
destroy(err) {
// 错误处理
}
})
这种模式特别适合:
- 大型静态页面的渐进式渲染
- 流式传输中的优先级控制
- 与CDN边缘计算的集成
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn