ssr文档学习

2020-01-09  本文已影响0人  鱼竿23333

Vue SSR

服务器端渲染

Vue.js 可以将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序

为什么使用服务器端渲染 (SSR)?

需权衡之处:

基本用法

渲染一个 Vue 实例

1 npm init
新建一个项目
2 npm install vue vue-server-renderer --save
新建index.js

// 第 1 步:创建一个 Vue 实例
const Vue=require('vue');

const app=new Vue({
    template:`<div>Hello</div>`
})
// 第 2 步:创建一个 renderer
const renderer=require('vue-server-renderer').createRenderer();
// 第 3 步:将 Vue 实例渲染为 HTML
renderer.renderToString(app,(err,html)=>{
    if(err){
        throw err
    }
    console.log(html)
})
// 在 2.5.0+,如果没有传入回调函数,则会返回 Promise:
renderer.renderToString(app).then(html=>{
    console.log(html)
}).catch(err => {
    console.error(err)
  })

在终端node index.js运行出现<div>Hello</div>

与服务器集成

1 npm install express --save
将index.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>
            `)
    })
})


// renderer.renderToString(app).then(html=>{
//     console.log(html)
// }).catch(err => {
//     console.error(err)
//   })
server.listen(8080)

在浏览器打开localhost:8080 出现页面

使用一个页面模板

用一个额外的 HTML 页面包裹容器,来包裹生成的 HTML 标记
=====》直接在创建 renderer 时提供一个页面模板

多数时候,我们会将页面模板放在特有的文件中,例如 index.template.html

<!DOCTYPE html>
<html lang="en">
  <head><title>Hello</title></head>
  <body>
    <!--vue-ssr-outlet-->
  </body>
</html>

注意

<!--vue-ssr-outlet-->

注释 -- 这里将是应用程序 HTML 标记注入的地方。

继续将index.js改写:

const Vue=require('vue');
const server = require('express')()


const renderer=require('vue-server-renderer').createRenderer({
    template: require('fs').readFileSync('./index.template.html', 'utf-8')
});


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(html) //html 将是注入应用程序内容的完整页面
    })
})


// renderer.renderToString(app).then(html=>{
//     console.log(html)
// }).catch(err => {
//     console.error(err)
//   })
server.listen(8080)
模板插值

如下模板:

<html>
  <head>
    <!-- 使用双花括号(double-mustache)进行 HTML 转义插值(HTML-escaped interpolation) -->
    <title>{{ title }}</title>

    <!-- 使用三花括号(triple-mustache)进行 HTML 不转义插值(non-HTML-escaped interpolation) -->
    {{{ meta }}}
  </head>
  <body>
    <!--vue-ssr-outlet-->
  </body>
</html>

过传入一个"渲染上下文对象",作为 renderToString 函数的第二个参数,来提供插值数据:

const Vue=require('vue');
const server = require('express')()

const context = {
    title: '22',
    meta: `
      <meta ...>
      <meta ...>
    `
  }
const renderer=require('vue-server-renderer').createRenderer({
    template: require('fs').readFileSync('./index.template2.html', 'utf-8')
});


server.get('*',(req,res)=>{
    const app=new Vue({
        data: {
            url: req.url
          },
        template:`<div>dddd</div>`
    })

    renderer.renderToString(app,context,(err,html)=>{
        console.log(html)
        if(err){
            res.status(500).end('Internal Server Error')
            return
        }
        res.end(html)
    })
})


// renderer.renderToString(app).then(html=>{
//     console.log(html)
// }).catch(err => {
//     console.error(err)
//   })
server.listen(8090)

npm install webpack
npm install webpack-cli
npm install webpack-merge
npm install webpack-node-externals
npm install vue-loader
npm install vue-template-compiler
npm install url-loader

上一篇 下一篇

猜你喜欢

热点阅读