预渲染:构建阶段生成匹配预渲染路径的 html 文件(注意:每个需要预渲染的路由都有一个对应的 html)。构建出来的 html 文件已有部分内容
服务端渲染:用户访问 url,服务端根据访问路径请求所需数据,拼接成 html 字符串,返回给前端。前端接收到 html 时已有部分内容;
第一部分:预渲染(Prerending)(prerender-spa-plugin)
一、搭建
1.vue init webpack
2.npm install
3.npm run dev
4.npm install prerender-spa-plugin -D
二、添加路由组件,并把vue路由配置为history模式
mode: 'history'三、开始使用配置
1.https://github.com/chrisvfritz/prerender-spa-plugin(webpack里面配置使用方法网址)
2.webpack.prod.conf.js配置
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const PrerenderSPAPlugin = require('prerender-spa-plugin')
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, '../dist'),
routes: ['/', '/about'],
renderer: new Renderer({
inject: {
foo: 'far'
},
headless: false,
// 在项目的入口中使用document.dispatchEvent(new Event('render-event'))
renderAfterDocumentEvent: 'render-event'
})
}),
3.main.js配置
mounted() {
document.dispatchEvent(new Event('render-event'))
}四、打包、启动
1.打包
// 生成dist文件
npm run build2.服务器端启动,使用到了 http-server
// 控制台 cd dist,执行下方命令
hs -o -p 9999五、浏览器f12查看NetWork->Response下的内容

首次请求可以看到已经有内容了~优秀
第二部分:服务端渲染(SSR)(vue-server-renderer)【待更新,学习中ing】
一、定义+优点
1.什么是服务端渲染?(Server Side Rendering)
Vue.js是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出Vue组件,进行生成DOM和操作DOM,然而也可以将同一个组件渲染为服务器端的HTML字符串,将它们直接发送到浏览器,最后将这些静态标记“激活”为客户端上完全可交互的应用程序。

2.服务端渲染优点有哪些?
- 更快的构建速度,SSR是动态插入数据,并不会在构建时就去预加载数据,而是输入url后在服务端请求,拿到返回的数据插入模板后再返回给客户端。
- 嵌套路由下的个性化页面加载速度,个性化页面无法进行预渲染,ssr却可以解决。
- 更好的SEO。
- 更快的首屏加载速度。( 请求业务数据,和将数据转为html片段都在服务端进行了,浏览器负责加载资源,请求CDN资源,css渲染。到达时间缩短。之后走的依旧是前端路由,然后前端预取数据,所以这里仅仅首屏 )。

二、简单搭建
1.init创建项目
1) npm init --yes
2) npm i vue express vue-server-renderer -S // 安装 vue、express服务端应用框架、vue-server-renderer2.创建server.js文件
const Vue = require('vue')
const express = require('express')() // 创建服务端的渲染器
const renderer = require('vue-server-renderer').createRenderer()
const app = new Vue({
template:'<div>hello world</div>'
})
express.get('/',(req,res)=>{
renderer.renderToString(app,(err,html)=>{
if(err){
return res.state(500).end('运行时错误')
}
res.send(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue2.0 SSR渲染页面</title>
</head>
<body>
${html}
</body>
</html>
`)
})
})
express.listen(8080,()=>{
console.log('服务器已经启动!')
})
解读:

3.启动查看
node server.js4.浏览器f12查看NetWork->Response已经有了html内容
三、配置文件
1.打开一个之前webpack构建好的vue项目

2.把server.js添加进去,如上图最下方
3.配置package.json,添加命令
"server": "webpack --config build/webpack.server.conf.js"
4.添加并配置/build/webpack.server.conf.js文件
5.注释入口文件
入口文件不再是main.js,应该是服务端的入口文件,接下来配置

6.添加入口文件entry-server.js

解决vue单例的问题,实现每次点击都调用
7.更改main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import {createRouter} from './router'
Vue.config.productionTip = false
// 单例
/* eslint-disable no-new */
export function createApp() {
const router = createRouter()
const app = new Vue({
router,
components: { App },
template: '<App/>'
})
return { app }}
}8.更改router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import About from '@/components/About'
import Home from '@/components/Home'
Vue.use(Router)
export function createRouter() {
return new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
]
})
}
9.配置entry-server.js
import { createApp } from './main'
export default context => {
return new Promise((resolve, reject)=> {
const { app } = createApp
const router = app.$router
const { url } = context
const { fullPath } = router.resolve(url).route
if (fullPath !== url) {
return reject({url: fullPath})
}
// 更改路由
router.push(url)
// wait until router has resolved possible async hooks
router.onReady(()=> {
const matchedComponents = router.getMatchedComponents()
// no matched routes
if (!matchedComponents.length) {
return reject({code: 404})
}
resolve(app)
}, reject)
})
}10.执行命令
npm run server