简易实现ssr
2026/7/29 4:15:55 网站建设 项目流程

vue3

1. 项目结构

src/ ├── entry-server.js # 服务端入口 ├── entry-client.js # 客户端入口(水合) ├── App.vue server.js # Node服务 index.html # HTML模板

2. 关键代码

server.js(Node 服务)

import express from 'express' import { createSSRApp } from 'vue' import { renderToString } from '@vue/server-renderer' import App from './App.vue' const app = express() app.get('*', async (req, res) => { // 1. 创建Vue实例(服务端) const vueApp = createSSRApp(App) // 2. 渲染组件 → HTML字符串 const html = await renderToString(vueApp) // 3. 返回完整页面,注入渲染出来的html res.send(` <!DOCTYPE html> <html> <body> <!-- 服务端渲染生成的HTML --> <div id="app">${html}</div> <!-- 客户端代码,用来水合激活交互 --> <script src="/client.js"></script> </body> </html> `) }) app.listen(3000, () => console.log('ssr server 3000'))

entry-client.js(客户端水合)

import { createSSRApp } from 'vue' import App from './App.vue' const app = createSSRApp(App) // hydrate:水合,把服务端静态HTML绑定事件,变成可交互页面 app.mount('#app', true)

App.vue

<template> <div> <h1>Vue SSR页面</h1> <p>{{ msg }}</p> <button @click="clickHandle">点我</button> </div> </template> <script setup> const msg = '服务端渲染内容' const clickHandle = () => alert('按钮交互') </script>

3. SSR 核心流程

  1. 用户请求页面 → Node 服务启动 Vue 应用
  2. renderToString在服务端执行组件,生成静态 HTML 字符串
  3. HTML 直接返回浏览器,首屏立刻看到内容(利于 SEO、首屏加载)
  4. 浏览器加载客户端 js,执行hydrate水合
  5. 水合:对比已有 DOM,绑定事件,页面拥有交互能力

4. 两个核心概念区分

  • SSR(服务端渲染)renderToString,输出 HTML 字符串,无交互
  • 水合 (hydration):客户端复用已有 DOM,附加事件,避免重新创建 DOM

5. 极简面试一句话总结

SSR 在 Node 服务端运行 Vue 组件,通过renderToString将组件编译为 HTML 返回浏览器,实现快速首屏展示;客户端执行水合,为静态 DOM 绑定交互事件。

补充:和 SPA 区别

SPA:浏览器下载 js 后才渲染页面,空白屏; SSR:浏览器直接收到完整 HTML,首屏有内容,SEO 友好。

react

项目最简结构

server.js # Node服务 src/ ├── App.jsx # 组件 ├── entry-server.js # 服务端入口 └── entry-client.js # 客户端水合入口 index.html # HTML模板

1. App.jsx

export default function App() { return ( <div> <h1>React SSR Demo</h1> <p>服务端渲染出来的文字</p> <button onClick={() => alert('水合成功,可以点击!')}>点击测试</button> </div> ) }

2. entry-server.js(服务端渲染代码)

import { renderToString } from 'react-dom/server' import App from './App' export function render() { // 将组件渲染成HTML字符串 return renderToString(<App />) }

3. entry-client.js(客户端水合)

import { hydrateRoot } from 'react-dom/client' import App from './App' // 复用服务端输出的DOM,绑定事件(水合) hydrateRoot(document.getElementById('root'), <App />)

4. server.js(核心 Node 服务)

import express from 'express' import { render } from './src/entry-server.js' const app = express() // 托管打包后的客户端js静态资源 app.use(express.static('./dist/client')) app.get('*', async (req, res) => { // 1. 服务端渲染组件,得到html字符串 const appHtml = render() // 2. 返回完整HTML,注入渲染内容 + 引入客户端水合js const html = ` <!DOCTYPE html> <html> <body> <div id="root">${appHtml}</div> <!-- 客户端打包产物,用来水合 --> <script src="/entry-client.js"></script> </body> </html> ` res.send(html) }) app.listen(3000, () => console.log('React SSR 运行在3000'))

完整执行流程

  1. 浏览器访问页面 → Node 服务调用renderToString(<App/>),生成静态 HTML
  2. 返回 HTML 给浏览器,页面直接展示内容(此时按钮不能点击)
  3. 浏览器加载entry-client.js
  4. 执行hydrateRoot,对比现有 DOM,绑定事件,页面拥有交互

React SSR 和 Vue3 SSR 关键相同点

  1. 都需要两份入口文件:服务端渲染入口、客户端水合入口
  2. 服务端:只输出 HTML 字符串,不挂载 DOM
  3. 客户端:执行水合 hydrate,复用已有 DOM,添加交互

面试高频区分

✅ Vue3:renderToString+createSSRApp().mount('#app', true)✅ React18:renderToString+hydrateRoot

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询