前提条件
因为这个涉及到了许多知识,了解一点的话更容易理解
- vue
- webpack (简单了解)
- nodejs (简单了解)
我就直接讲基本概念吧.. SSR 服务器渲染 , 意思是 由服务器来进行将Vue 组件进行渲染 ... 并且挂载至模板上(html)
首先我们来讲讲普通的vue渲染 ...
首先我们知道, 如果我们用vue-cli创建一个普通的项目 , 在mian.js 里面有这样一句话 ..
import App from './App.vue' // 引入App.vue 这个组件
new Vue ({
render : h => h(App) // 这个Vue实例将直接渲染App组件
}).$mount('#root'); // 将这个Vue 实例挂载到id为 root 节点上
那么以上是我们vue-cli 创建出来的 main.js 里面的代码,那么我们这串代码呢,是从客户端运行,为什么能看出来是客户端运行的呢, 其实很简单,你使用一个console.log,那么这个console.log 会在浏览器里面运行, 那么这个就是客户端环境,所以呢,这个是Vue的客户端渲染
然后我们来直接看看服务端渲染(其实官网都有代码,官网也比我说的好很多,但是一开始会让人很蒙... 特别是webpack构建那里) SSR 官方文档
首先我们还是安装官方文档走 安装必备环境
- 安装SSR必备的依赖 vue 和 vue-server-renderer 因为之后就是靠这个vue-server-renderer 这个依赖去渲染
npm install vue vue-server-renderer --save
- 渲染一个Vue 实例渲染到html上面
// 第 1 步:创建一个 Vue 实例
const Vue = require('vue')
const app = new Vue({
template: `<div>Hello World</div>`
})
// 第 2 步:创建一个 renderer
const renderer = require('vue-server-renderer').createRenderer()
// 第 3 步:将 Vue 实例渲染为 HTML
// 通过renderer.renderToString() 将这个app 挂载到模板上 生成的html 字符串给客户端,意思是直接给浏览器一个页面
// vue-ssr 定义本来也就如此嘛
renderer.renderToString(app, (err, html) => {
if (err) throw err
console.log(html)
// => <div data-server-rendered="true">Hello World</div>
})
- 与服务器集成
首先先安装express来进行nodejs服务端开发 npm install express --save
const Vue = require('vue') // 引入vue 依赖
const server = require('express')() // 创建出一个服务器 , 这个属于 express 用法
const renderer = require('vue-server-renderer').createRenderer() // 创建一个renderer
// 不管任何请求都会进入这个方法
/*
如果你的服务器启动的是localhost:8080 ,那么你访问 localhost:8080/index or localhost:8080/xxx 都会进入这个方法
req : 请求
res : 响应
*/
server.get('*', (req, res) => {
// 不管任何请求 , 都创建出一个vue 实例 , 而这个实例显示得内容为template 中的内容
const app = new Vue({
data: {
url: req.url
},
template: `<div>访问的 URL 是: {{ url }}</div>`
})
// 这个vue 实例 渲染成html文本 ....
renderer.renderToString(app, (err, html) => {
if (err) {
// 如果渲染出错了, 或者其他错误 ..
// 直接响应出500 错误 , 并且返回的字符串为 .... xxxx
res.status(500).end('Internal Server Error')
return
}
// 如果一切正常, 将渲染出的html文本 放入到body中 一起给浏览器
res.end(`
<!DOCTYPE html>
<html lang="en">
<head><title>Hello</title></head>
<body>${html}</body>
</html>
`)
})
})
server.listen(8080)
- 使用一个页面模板
// 创建出一个html 模板, 名叫 index.template.html
内容为
<!DOCTYPE html>
<html lang="en">
<head><title>Hello</title></head>
<body>
<!-- 这个代码不能删, 这个地方存在的意义在于,等会我们会把之前Vue实例渲染出来的html 代码放到这里 -->
<!--vue-ssr-outlet-->
</body>
</html>
//然后将 第三部的服务器 renderer 换一种获取方式
const renderer = createRenderer({
template: require('fs').readFileSync('./index.template.html', 'utf-8')
})
// 并且直接生成html ,不需要在使用第三步中的end 中的字符串手动拼接到body上面
renderer.renderToString(app, (err, html) => {
console.log(html) // html 将是注入应用程序内容的完整页面
})
const Vue = require('vue') // 引入vue 依赖
const server = require('express')() // 创建出一个服务器 , 这个属于 express 用法
创建并且增加一个模板
const renderer = require('vue-server-renderer').createRenderer({
template: require('fs').readFileSync('./index.template.html', 'utf-8')
})
// 不管任何请求都会进入这个方法
/*
如果你的服务器启动的是localhost:8080 ,那么你访问 localhost:8080/index or localhost:8080/xxx 都会进入这个方法
req : 请求
res : 响应
*/
server.get('*', (req, res) => {
// 不管任何请求 , 都创建出一个vue 实例 , 而这个实例显示得内容为template 中的内容
const app = new Vue({
data: {
url: req.url
},
template: `<div>访问的 URL 是: {{ url }}</div>`
})
// 这个vue 实例 渲染成html文本 ....
renderer.renderToString(app, (err, html) => {
if (err) {
// 如果渲染出错了, 或者其他错误 ..
// 直接响应出500 错误 , 并且返回的字符串为 .... xxxx
res.status(500).end('Internal Server Error')
return
}
// 如果一切正常, 将渲染出的html文本 直接给浏览器
res.end(html)
})
})
server.listen(8080)
好了 这就是一个有模板的 服务器渲染Demo