You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3项目仅指定两个页面实现SSR方案咨询(无需迁移Nuxt.js)

Vue3 单项目中仅指定页面实现SSR方案(无需Nuxt.js)

先解决你遇到的「仅能接受字符串化Vue根组件」问题

你之前按官方文档配置时的核心问题大概率是复用了单例Vue实例,服务端是多请求并发环境,必须为每个请求创建全新的Vue实例和路由实例,否则会导致状态污染,进而出现只能处理字符串化根组件的异常。


分步实现仅指定页面SSR

1. 调整项目结构

拆分客户端/服务端入口,抽离共享路由配置:

src/
├─ entry-client.js   # 客户端入口
├─ entry-server.js   # 服务端入口
└─ router/
   └─ index.js       # 共享路由配置

2. 配置带SSR标记的路由

在路由meta中标记需要SSR的页面,方便服务端识别:

// src/router/index.js
import { createRouter, createWebHistory, createMemoryHistory } from 'vue-router'

const routes = [
  // 需要SSR的页面
  {
    path: '/page-a',
    component: () => import('../views/PageA.vue'),
    meta: { ssr: true }
  },
  {
    path: '/page-b',
    component: () => import('../views/PageB.vue'),
    meta: { ssr: true }
  },
  // 其余CSR页面
  {
    path: '/',
    component: () => import('../views/Home.vue')
  }
]

// 根据环境创建路由实例(服务端用memoryHistory)
export function createRouterInstance() {
  return createRouter({
    history: import.meta.env.SSR ? createMemoryHistory() : createWebHistory(),
    routes
  })
}

3. 编写服务端入口

每次请求创建全新Vue实例,处理路由匹配与渲染:

// src/entry-server.js
import { createSSRApp } from 'vue'
import { createRouterInstance } from './router'
import App from './App.vue'

export async function render(url) {
  // 为每个请求创建独立实例
  const app = createSSRApp(App)
  const router = createRouterInstance()
  app.use(router)

  // 跳转至请求URL
  await router.push(url)
  await router.isReady()

  // 获取匹配的路由记录,判断是否需要SSR
  const matchedRoute = router.currentRoute.value.matched[0]
  if (!matchedRoute?.meta?.ssr) {
    return { html: '' } // 返回空,交由客户端CSR处理
  }

  // 处理页面异步数据(如果有)
  if (matchedRoute.components.default.asyncData) {
    await matchedRoute.components.default.asyncData({ router })
  }

  // 渲染为HTML字符串
  const html = await app.renderToString()
  return { html, router }
}

4. 编写客户端入口

客户端激活服务端渲染的HTML:

// src/entry-client.js
import { createApp } from 'vue'
import { createRouterInstance } from './router'
import App from './App.vue'

const app = createApp(App)
const router = createRouterInstance()
app.use(router)

router.isReady().then(() => {
  app.mount('#app')
})

5. 配置Node.js服务(以Express为例)

判断请求路由是否需要SSR,动态返回渲染结果:

// server.js
import express from 'express'
import fs from 'fs'
import path from 'path'
import { createRequire } from 'module'
const require = createRequire(import.meta.url)

const app = express()
const PORT = process.env.PORT || 3000

// 读取HTML模板
const template = fs.readFileSync(path.resolve(__dirname, 'dist/client/index.html'), 'utf-8')
// 导入服务端渲染入口(构建后的文件)
const { render } = require('./dist/server/entry-server.js')

// 静态文件服务(客户端构建产物)
app.use(express.static(path.resolve(__dirname, 'dist/client'), { index: false }))

// 处理所有路由请求
app.get('*', async (req, res) => {
  try {
    const { html } = await render(req.url)
    // 如果是SSR页面,注入渲染内容;否则直接返回原模板
    const finalHtml = html ? template.replace('<!--ssr-outlet-->', html) : template
    res.status(200).set({ 'Content-Type': 'text/html' }).end(finalHtml)
  } catch (e) {
    console.error(e)
    res.status(500).end('Server Error')
  }
})

app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`)
})

6. 配置Vite构建

修改vite.config.js,添加SSR构建配置:

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'

export default defineConfig({
  plugins: [vue()],
  build: {
    ssr: true,
    outDir: 'dist',
    rollupOptions: {
      input: {
        client: resolve(__dirname, 'index.html'),
        server: resolve(__dirname, 'src/entry-server.js')
      }
    }
  }
})

7. 调整HTML模板

在index.html中添加SSR内容占位符:

<!-- index.html -->
<body>
  <div id="app"><!--ssr-outlet--></div>
  <script type="module" src="/src/entry-client.js"></script>
</body>

官方文档相关内容翻译(SSR vs SSG)

SSR 对比 SSG

服务端渲染(SSR)指在服务器上为每个请求实时渲染页面,随后将完整HTML发送至客户端。客户端接收HTML后,会激活Vue应用使其具备交互能力。

静态站点生成(SSG)也叫预渲染,是在构建阶段为所有页面生成静态HTML文件。这些文件可部署至任意静态文件服务器,用户请求时直接提供,无需服务器实时渲染。

SSR适合内容频繁更新或需根据请求动态生成内容的场景;SSG则适合内容相对静态、可提前预渲染的场景,拥有更优的性能与成本优势。

内容的提问来源于stack exchange,提问作者mahmoud hmaserv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 08:34:53