
vue31. 項目結構src/ ├── entry-server.js # 服務端入口 ├── entry-client.js # 客戶端入口水合 ├── App.vue server.js # Node服務 index.html # HTML模板2. 關鍵代碼server.jsNode 服務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 idapp${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.vuetemplate div h1Vue SSR頁面/h1 p{{ msg }}/p button clickclickHandle點我/button /div /template script setup const msg 服務端渲染內容 const clickHandle () alert(按鈕交互) /script3. SSR 核心流程用戶請求頁面 → Node 服務啟動 Vue 應用renderToString在服務端執行組件生成靜態 HTML 字符串HTML 直接返回瀏覽器首屏立刻看到內容利于 SEO、首屏加載瀏覽器加載客戶端 js執行hydrate水合水合對比已有 DOM綁定事件頁面擁有交互能力4. 兩個核心概念區分SSR服務端渲染renderToString輸出 HTML 字符串無交互水合 (hydration)客戶端復用已有 DOM附加事件避免重新創建 DOM5. 極簡面試一句話總結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.jsxexport default function App() { return ( div h1React 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 idroot${appHtml}/div !-- 客戶端打包產物用來水合 -- script src/entry-client.js/script /body /html res.send(html) }) app.listen(3000, () console.log(React SSR 運行在3000))完整執行流程瀏覽器訪問頁面 → Node 服務調用renderToString(App/)生成靜態 HTML返回 HTML 給瀏覽器頁面直接展示內容此時按鈕不能點擊瀏覽器加載entry-client.js執行hydrateRoot對比現有 DOM綁定事件頁面擁有交互React SSR 和 Vue3 SSR 關鍵相同點都需要兩份入口文件服務端渲染入口、客戶端水合入口服務端只輸出 HTML 字符串不掛載 DOM客戶端執行水合 hydrate復用已有 DOM添加交互面試高頻區分? Vue3renderToStringcreateSSRApp().mount(#app, true)? React18renderToStringhydrateRoot