Vue SSR 指南(一)

本文详细介绍了如何一步步搭建Vue Server-Side Rendering(VueSSR)应用,从创建项目、渲染Vue实例,到与服务器集成,使用页面模板,以及模板插值。通过实际操作展示了VueSSR的基本流程,包括设置Express服务器,读取HTML模板文件,以及处理每个请求时创建新的Vue实例以避免状态污染。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Vue SSR 指南(一)

根据官网按步骤实现Vue SSR搭建过程

命令构建项目初始化 : 新建一个文件夹 ssr

cd ssr
npm init -y
npm install vue vue-server-renderer express --save 
或者yarn add vue vue-server-renderer express --save
渲染一个 Vue 实例

1.新建文件server1.js

// 1、创建一个vue实例
const Vue = require('vue')
const app = new Vue({
    template:`<div>hello ssr</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)
})

2.运行命令node server.js,控制台会输出两行<div data-server-rendered="true">Hello ssr</div>

与服务器集成

1.新建文件server2.js (npm install express --save)

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.writeHead(200, { 'Content-Type': 'text/html;charset=utf-8' }) //writeHeader可以设置http返回状态码,多个http响应头。但是setHeader只针对单一属性的设置。
    // res.setHeader('Content-Type', 'text/html;charset=UTF-8') //解决乱码  注意:文件必须是utf-8格式
    res.end(`
      <!DOCTYPE html>
      <html lang="en">
        <head><title>Hello</title></head>
        <body>${html}</body>
      </html>
    `)
  })
})

server.listen(8080)

2.运行命令node server2.js,浏览器打开 localhost:8080
在这里插入图片描述

使用一个页面模板

1.使用页面模板,新建文件index.template.html 。注意 <!--vue-ssr-outlet--> 注释 – 这里将是应用程序 HTML 标记注入的地方

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>vue ssr</title>
  </head>
  <body>
    <!--vue-ssr-outlet-->
  </body>
</html>

2.新建文件server3.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)
  })
})
server.listen(8080)

模板插值

1.使用页面模板,新建文件index.template1.html

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

2.新建server4.js

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

server.get('*', (req, res) => {
  const app = new Vue({
    data: {
      url: req.url,
    },
    template: `<div>您访问的URL: {{url}}</div>`,
  })
  const context = {
    title: 'Vue ssr',
    meta: `
    <meta charset="utf-8">
    `,
  }
  renderer.renderToString(app, context, (err, html) => {
    if (err) {
      res.status(500).end('Internal Server Error')
      return
    }
    res.end(html)
  })
})
server.listen(8080)
源码结构,避免避免状态单例

为每个请求创建一个新的根vue实例,避免请求共享,状态污染。暴露一个可以重复执行的工厂函数,为每个请求创建新的应用程序实例:

1.新建app.js

const Vue = require('vue')

module.exports = function createApp(context) {
  return new Vue({
    data: {
      url: context.url,
    },
    template: `<div>{{url}}</div>`,
  })
}

2.新建server.js

const createApp = require('./app')
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 = createApp({ url: req.url })
  renderer.renderToString(app, (err, html) => {
    if (err) {
      res.status(500).end('Internal Server Error')
      return
    }
    console.log('html: ', html)
    res.end(html)
  })
})

server.listen(8080)

3.运行node server.js

源码

目录结构下的ssr

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值