服务器端渲染-Vue SSR搭建

阅读建议:建议通过左侧导航栏进行阅读
文章简介:本文是Vue.js服务器端渲染的另一种解决方案-SSRServer-Side Rendering)学习笔记

Vue SSR是什么

官方文档解释:Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM。然而,也可以将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。
服务器渲染的 Vue.js 应用程序也可以被认为是"同构"或"通用",因为应用程序的大部分代码都可以在服务器和客户端上运行。

  • Vue SSRVue.js Server-Side Rendering)是 Vue.js 官方提供的服务端渲染解决方案
  • 使用SSR,可以构建基于vue.js的同构应用

Vue SSR使用场景

在使用SSR之前,要从以下两方面考虑是否真的需要它。

技术层面

  • 有 利于SEO
  • 更快的首屏渲染速度

业务层面

  • 不适合管理系统
  • 适合移动网站和门户资讯类网站,如企业官网、知乎、简书等

Vue SSR实现方案

基于 Vue SSR 官方文档提供的解决方案

官方方案具有更直接的控制应用程序的结构,更深入底层,更加灵活,同时在使用官方方案的过程中,也会对Vue SSR有更加深入的了解。
该方式需要你熟悉 Vue.js 本身,并且具有 Node.jswebpack 的相当不错的应用经验。

Nuxt.js 开发框架

Nuxt.js提供了平滑的开箱即用的体验,它建立在同等的Vue.js技术栈之上,但抽象出很多模板,并提供了一些额外的功能,例如静态站点生成。通过 Nuxt.js 可以快速的使用 Vue SSR 构建同构应用。

Vue SSR基于官方文档的基本使用

渲染一个Vue实例

体会服务端渲染中最基础的工作-模板渲染,了解如何使用 Vue SSR 将一个 Vue 实例渲染为 HTML 字符串,也就是如何在服务端使用 Vue.js 的方式解析替换字符串。

新建一个项目,在项目根目录下依次执行以下命令

//初始化项目,新建package.json
yarn init
//安装项目基本依赖包
yarn add vue vue-server-renderer express

在项目根目录下分别新建server.jsindex.html

server.js

const Vue = require('vue');
const express = require('express');
const fs = require('fs');
const renderer = require('vue-server-renderer').createRenderer({
   
    //使用utf-8进行编码的index.html作为渲染模板
    template: fs.readFileSync('./index.html', 'utf-8')
});
const server = express();

//设置路由,客户端以get请求网站根路径
server.get('/', (req, res) => {
   
    //创建一个vue实例
    const app = new Vue({
   
        template:`
            <div>
                <h1>{
    {message}}</h1>
            </div>
        `,
        data: {
   
            message: '创建一个vue实例' 
        }
    });
    
    //将vue实例转换为html字符串,并发送给客户端
    renderer.renderToString(app, {
   
        title: '服务器端渲染',
        meta: `<meta name="desc" content="服务器">`
    }, (err, html) => {
   
        if(err) {
   
            res.status(500).end('server error...');
        };
        
        res.end(html);
    })
})

//启动web服务
server.listen(3000, () => {
   console.log('server running...')})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    {
  {
  { meta }}}
    <title>{
  {title}}</title>
</head>
<body>
  <!--标记页面模板-->
  <!--vue-ssr-outlet-->  
</body>
</html>

使用nodemon server.js(nodemon需要在本机安装)启动项目。
在客户端访问http://localhost:3000/,可以看到渲染结果,页面结构:

在这里插入图片描述案例总结:

  • 解决页面显示乱码的两种方案

1、设置响应头

res.setHeader('Content-Type', 'text/html;charset=utf8');
res.end(html); 

2、发送完整的html页面,使用charset="UTF-8"进行编码

res.end(`
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
       ${
     html} 
    </body>
    </html>
`)
  • 服务端向客户端发送完整页面的两种方式

1、利用ES6的模板语法直接在请求响应中发送完整页面模板
2、使用渲染模板,结合vue-server-renderer解析替换字符串,如server.js就采用这种方式

注意:
1.使用渲染模板接收外部数据时,如果修改的是静态模板如head中的内容,需要重启项目才能生效,因为模板是在项目启动时获取的
2.如果需要将外部数据渲染为html标签,需要使用三个“{}”,如{ { { meta }}}

Vue SSR同构渲染构建

构建流程

在这里插入图片描述

源码结构

1.使用webpack打包的原因

  • 通常 Vue 应用程序是由 webpackvue-loader 构建,并且许多 webpack 特定功能不能直接在 Node.js 中运行(例如通过 file-loader 导入文件,通过 css-loader 导入 CSS
  • 尽管 Node.js 最新版本能够完全支持 ES2015 特性,我们还是需要转译客户端代码以适应老版浏览器。这也会涉及到构建步骤。

对于客户端应用程序和服务器应用程序,我们都要使用 webpack 打包 - 服务器需要「服务器 bundle」然后用于服务器端渲染(SSR),而「客户端 bundle」会发送给浏览器,用于混合静态标记。

2.使用webpack的源码结构
使用 webpack 来处理服务器和客户端的应用程序,大部分源码可以使用通用方式编写,可以使用 webpack 支持的所有功能,推荐的源码结构:

src
├── components
│   ├── Foo.vue
│   ├── Bar.vue
│   └── Baz.vue
├── App.vue
├── app.js # 通用 entry(universal entry)
├── entry-client.js # 仅运行于浏览器
└── entry-server.js # 仅运行于服务器

在项目根目录下新建src目录

src/app.vue

<template>
  <div id="app">
    <h1>{
  { message }}</h1>
    <h2>客户端动态交互</h2>
    <div>
      <input v-model="message" />
    </div>
    <div>
      <button @click="onClick">点击按钮</button>
    </div>
  </div>
</template>

<script>
export default {
    
  data() {
    
    return {
    
      message: "创建一个vue实例",
    };
  },
  methods: {
    
    onClick() {
    
      console.log("---点击按钮---");
    },
  },
};
</script>

src/app.js

app.js 是我们应用程序的「通用 entry」,简单地导出一个工厂函数createApp 函数,用于创建新的应用程序、router 和 store 实例。

/**
 * 通用启动入口
 */

import Vue from 'vue'
import App from './App.vue'

// 导出一个工厂函数,用于创建新的
// 应用程序、router 和 store 实例
export function createApp () {
   
  const app = new Vue({
   
    // 根实例简单的渲染应用程序组件。
    render: h => h(App)
  })
  return {
    app }
}

src/entry-client.js

客户端 entry 只需创建应用程序,并且将其挂载到 DOM 中。

import {
    createApp } from './app'

// 客户端特定引导逻辑……

const {
    app } = createApp()

//将创建的vue实例绑定
app.$mount('#app')

src/entry-server.js

服务器 entry 使用 default export 导出函数,并在每次渲染中重复调用此函数。此时,除了创建和返回应用程序实例之外,它不会做太多事情 - 但是稍后我们将在此执行服务器端路由匹配 (server-side route matching) 和数据预取逻辑 (data pre-fetching logic)

import {
    createApp } from './app'

export default context => {
   
  const 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值