技术文档中心
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
  • Vue2 基础

    • Vue 学习指南
    • Vue2 快速入门
    • Vue2 模板语法
    • Vue2 组件基础
    • Vue2 计算属性与侦听器
    • Vue2 生命周期
  • Vue2 进阶

    • Vue2 组件通信
    • Vue2 插槽详解
    • Vue2 混入与自定义指令
    • Vue2 过渡与动画
    • Vuex 状态管理
  • Vue2 高级

    • Vue2 性能优化
    • Vue2 服务端渲染(SSR)
    • Vue2 源码解析
  • Vue3 基础

    • Vue3 快速入门
    • Vue3 Composition API
    • Vue3 响应式系统
    • Vue3 组件基础
    • Vue3 生命周期
  • Vue3 进阶

    • Vue3 组合式函数
    • Vue3 组件通信
    • Vue3 Teleport 与 Suspense
    • Pinia 状态管理
    • Vue Router 4
  • Vue3 高级

    • Vue3 TypeScript
    • Vue3 性能优化
    • Vue3 测试
    • Vue3 SSR
    • Vue3 源码解析
  • 实战项目

    • Vue2 实战项目
    • Vue3 实战项目
    • Vue2 迁移 Vue3

Vue3 SSR

什么是 SSR

服务端渲染(Server-Side Rendering)在服务器端将 Vue 组件渲染为 HTML。

优势

  • 更好的 SEO
  • 更快的首屏加载

劣势

  • 开发限制
  • 服务器负载
  • 部署复杂

使用 Vite SSR

项目结构

src/
├── components/
├── pages/
├── entry-client.js
├── entry-server.js
└── main.js

entry-client.js

import { createApp } from './main'

const { app, router } = createApp()

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

entry-server.js

import { createApp } from './main'
import { renderToString } from 'vue/server-renderer'

export async function render(url) {
  const { app, router } = createApp()
  
  await router.push(url)
  await router.isReady()
  
  const html = await renderToString(app)
  return html
}

main.js

import { createSSRApp } from 'vue'
import { createRouter, createMemoryHistory, createWebHistory } from 'vue-router'
import App from './App.vue'

export function createApp() {
  const app = createSSRApp(App)
  
  const router = createRouter({
    history: import.meta.env.SSR
      ? createMemoryHistory()
      : createWebHistory(),
    routes: [...]
  })
  
  app.use(router)
  
  return { app, router }
}

server.js

import express from 'express'
import { render } from './dist/server/entry-server.js'

const app = express()

app.get('*', async (req, res) => {
  const html = await render(req.url)
  
  res.send(`
    <!DOCTYPE html>
    <html>
      <head>
        <title>SSR App</title>
      </head>
      <body>
        <div id="app">${html}</div>
        <script type="module" src="/src/entry-client.js"></script>
      </body>
    </html>
  `)
})

app.listen(3000)

使用 Nuxt 3

创建项目

npx nuxi@latest init my-app
cd my-app
yarn install
yarn dev

目录结构

my-app/
├── assets/
├── components/
├── composables/
├── layouts/
├── middleware/
├── pages/
├── plugins/
├── public/
├── server/
├── app.vue
└── nuxt.config.ts

页面

<!-- pages/index.vue -->
<template>
  <div>
    <h1>{{ title }}</h1>
    <NuxtLink to="/about">About</NuxtLink>
  </div>
</template>

<script setup>
const { data: title } = await useFetch('/api/title')
</script>

布局

<!-- layouts/default.vue -->
<template>
  <div>
    <header>
      <nav>...</nav>
    </header>
    <slot />
    <footer>...</footer>
  </div>
</template>

API 路由

// server/api/hello.ts
export default defineEventHandler((event) => {
  return {
    message: 'Hello World'
  }
})

数据获取

<script setup>
// useFetch
const { data, pending, error, refresh } = await useFetch('/api/data')

// useAsyncData
const { data } = await useAsyncData('key', () => $fetch('/api/data'))

// useLazyFetch
const { pending, data } = useLazyFetch('/api/data')
</script>

状态管理

// composables/useCounter.ts
export const useCounter = () => {
  const count = useState('counter', () => 0)
  
  const increment = () => count.value++
  const decrement = () => count.value--
  
  return {
    count,
    increment,
    decrement
  }
}

中间件

// middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
  const user = useState('user')
  
  if (!user.value) {
    return navigateTo('/login')
  }
})
<script setup>
definePageMeta({
  middleware: 'auth'
})
</script>

插件

// plugins/myPlugin.ts
export default defineNuxtPlugin((nuxtApp) => {
  return {
    provide: {
      hello: (msg: string) => `Hello ${msg}!`
    }
  }
})
<script setup>
const { $hello } = useNuxtApp()
console.log($hello('World'))
</script>

部署

静态生成

yarn generate

Node.js 服务器

yarn build
node .output/server/index.mjs
最近更新: 2026/1/27 15:51
Contributors: hailong
Prev
Vue3 测试
Next
Vue3 源码解析