Vue2 服务端渲染(SSR)
什么是 SSR
服务端渲染(Server-Side Rendering)是指在服务器端将 Vue 组件渲染为 HTML 字符串,然后发送到浏览器。
SSR 优势
- 更好的 SEO
- 更快的首屏加载时间
SSR 劣势
- 开发条件限制
- 更多的服务器负载
- 部署复杂度增加
基本用法
安装依赖
yarn add vue vue-server-renderer express
服务器端代码
// server.js
const Vue = require('vue')
const server = require('express')()
const renderer = require('vue-server-renderer').createRenderer()
server.get('*', (req, res) => {
const app = new Vue({
data: {
url: req.url
},
template: `<div>访问的 URL 是: {{ url }}</div>`
})
renderer.renderToString(app, (err, html) => {
if (err) {
res.status(500).end('Internal Server Error')
return
}
res.end(`
<!DOCTYPE html>
<html lang="en">
<head><title>Hello</title></head>
<body>${html}</body>
</html>
`)
})
})
server.listen(8080)
使用 Nuxt.js
创建项目
yarn create nuxt-app my-app
cd my-app
yarn dev
目录结构
my-app/
├── assets/ # 未编译的资源
├── components/ # Vue 组件
├── layouts/ # 布局组件
├── middleware/ # 中间件
├── pages/ # 页面组件(自动生成路由)
├── plugins/ # Vue 插件
├── static/ # 静态文件
├── store/ # Vuex 状态树
└── nuxt.config.js # Nuxt 配置
页面组件
<!-- pages/index.vue -->
<template>
<div>
<h1>{{ title }}</h1>
<nuxt-link to="/about">About</nuxt-link>
</div>
</template>
<script>
export default {
async asyncData({ params }) {
const { data } = await fetch('https://api.example.com/data')
return { title: data.title }
},
head() {
return {
title: this.title,
meta: [
{ hid: 'description', name: 'description', content: 'My custom description' }
]
}
}
}
</script>
布局
<!-- layouts/default.vue -->
<template>
<div>
<header>
<nav>...</nav>
</header>
<nuxt />
<footer>...</footer>
</div>
</template>
Vuex Store
// store/index.js
export const state = () => ({
counter: 0
})
export const mutations = {
increment(state) {
state.counter++
}
}
export const actions = {
async nuxtServerInit({ commit }, { req }) {
// 服务端初始化
}
}
中间件
// middleware/auth.js
export default function ({ store, redirect }) {
if (!store.state.authenticated) {
return redirect('/login')
}
}
<script>
export default {
middleware: 'auth'
}
</script>
插件
// plugins/axios.js
export default function ({ $axios, redirect }) {
$axios.onError(error => {
if (error.response.status === 500) {
redirect('/error')
}
})
}
// nuxt.config.js
export default {
plugins: [
'~/plugins/axios'
]
}
部署
静态生成
yarn generate
服务端渲染部署
yarn build
yarn start
PM2 部署
pm2 start yarn --name "my-app" -- start