vuecli项目构建SSR服务端渲染的实现

yizhihongxing

下面是关于“vuecli项目构建SSR服务端渲染的实现”的完整攻略:

1. 什么是SSR?

SSR全称Server Side Rendering(服务端渲染),意思是将页面在服务器端进行渲染,然后再将已渲染的页面传输给客户端展示出来。

SSR的好处:

  • 更快的页面渲染速度,减少白屏时间
  • 更好的SEO(搜索引擎优化)
  • 更好的用户体验

2. Vue CLI 3 如何构建 SSR 服务端渲染应用?

Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供了项目的创建、编译、运行、构建等一系列功能的工具。

如果你想要构建一个 SSR 应用,可以使用Vue CLI脚手架提供的插件和配置进行构建。

2.1 安装 Vue CLI 3

首先,你需要安装 Vue CLI 3。在命令行中输入:

npm install -g @vue/cli

安装成功后,可以通过输入 vue --version 命令查看版本号,确保安装成功。

2.2 创建一个 SSR 应用

使用 Vue CLI 创建一个 SSR 应用非常简单,只需要在命令行中输入以下命令:

vue create my-ssr-app

其中,my-ssr-app 为创建的项目名称,你可以根据自己的需要进行修改。

在创建项目时,会有一个提示让你选择“需要预安装一些特性吗?”。这里我们选择 Manually select features,然后按下回车键。

在下一步中,除了选择 BabelRouter 这两个基础选项外,我们还需要选择 Server-Side Rendering (SSR)Vuex 这两个选项。

最后,按照提示完成项目的创建。

2.3 配置 SSR

项目创建完成后,需要进一步配置才能使其支持 SSR。

2.3.1 添加服务器文件

首先,在项目的根目录下创建一个 server.js 文件,并添加以下代码:

const fs = require('fs')
const path = require('path')
const express = require('express')
const server = express()

const resolve = file => path.resolve(__dirname, file)

const bundleRenderer = require('vue-server-renderer').createBundleRenderer(
  resolve('./dist/server-bundle/vue-ssr-server-bundle.json'), {
    runInNewContext: false,
    template: fs.readFileSync(resolve('./public/index.html'), 'utf-8')
  }
)

server.use('/dist', express.static(resolve('./dist')))

server.get('*', (req, res) => {
  const context = {
    title: 'Vue SSR Demo',
    url: req.url
  }

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

    res.end(html)
  })
})

const port = process.env.NODE_ENV === 'production' ? 80 : 8080

server.listen(port, () => {
  console.log(`Server started at http://localhost:${port}`)
})

其中,server.js 文件定义了一个节点服务器,并使用 vue-server-renderer 提供的 createBundleRenderer 创建了一个渲染器实例。在 server.get 里面,通过 vue-server-renderer 提供的 renderToString 进行服务端渲染。

2.3.2 添加打包配置

为了使打包生成的文件可以在服务器上运行,我们需要添加一些打包配置。

打开根目录下的 vue.config.js 文件,添加以下配置:

const path = require('path')

module.exports = {
  configureWebpack: {
    entry: {
      app: './src/entry-server.js'
    },
    output: {
      libraryTarget: 'commonjs2'
    },
    target: 'node',
    resolve: {
      alias: {
        '@': path.join(__dirname, './src')
      }
    }
  },

  chainWebpack: config => {
    config.plugins.delete('html')
    config.plugins.delete('preload')
    config.plugins.delete('prefetch')

    config
      .entry('app')
      .clear()
      .add('./src/entry-client.js')
      .end()

    config.output.filename('assets/js/[name].js')
    config.output.chunkFilename('assets/js/[name].js')

    config.optimization.splitChunks(false)
    config.module
      .rule('vue')
      .use('vue-loader')
      .tap(options => {
        options.optimizeSSR = false
        return options
      })
  }
}

其中,configureWebpack 中的配置项用于配置 Webpack,chainWebpack 是链式操作,可以修改 Webpack 中的默认配置。配置项的具体含义可以查看 Vue SSR 文档。

2.3.3 修改入口文件

src 目录下分别创建 entry-client.jsentry-server.js 文件,其中 entry-client.js 的内容默认已经生成,不需要修改。而 entry-server.js 需要添加以下内容:

import { createApp } from './main'

export default context => {
  const app = createApp()

  // 设置服务器端 router 的位置
  const router = app.$router
  router.push(context.url)

  context.meta = app.$meta()

  return new Promise((resolve, reject) => {
    router.onReady(() => {
      const matchedComponents = router.getMatchedComponents()

      if (!matchedComponents.length) {
        return reject({ code: 404 })
      }

      Promise.all(matchedComponents.map(Component => {
        if (Component.asyncData) {
          return Component.asyncData({
            store: app.$store,
            route: router.currentRoute
          })
        }
      })).then(() => {
        context.state = app.$store.state
        resolve(app)
      }).catch(reject)
    }, reject)
  })
}

3. 示例说明

接下来给出两个示例说明:

3.1 实例1

假设你需要从服务器获取一些数据,然后在页面中进行展示。你可以在组件生命周期函数中通过 axios 库发起请求,获取数据,然后在渲染函数中使用该数据。

在服务器端渲染中,由于没有浏览器环境,页面组件不会像在浏览器中一样被实例化和挂载到页面中,所以在服务器端需要在渲染函数执行之前先获取数据,并将这些数据提供给组件。

// Home.vue

<script>
export default {
  name: 'Home',

  asyncData ({ store }) {
    return store.dispatch('fetchData') // 从服务器获取数据
  },

  computed: {
    items () {
      return this.$store.state.items // 获取数据
    }
  },

  template: `<div>{{ items }}</div>`
}
</script>

其中,asyncData 是一个静态方法,它会在组件被实例化之前调用,从服务器获取数据后,将数据存储到 Vuex store 中,然后在组件的 computed 中以数据的形式注入到组件中。

3.2 实例2

假设你需要在服务器端进行一些路由控制,比如根据用户的权限判断是否能够访问某个页面。你可以在渲染函数执行之前先验证路由信息,然后再渲染页面。

// Auth.vue

<script>
export default {
  name: 'Auth',

  asyncData ({ store, route }) {
    if (route.path === '/admin' && !store.state.isAuthenticated) { // 判断用户是否已登录
      return Promise.reject({ code: 401, message: 'Unauthorized' }) // 如果用户未登录,跳转到401页面
    }
  },

  template: `<div>Welcome, Admin!</div>`
}
</script>

asyncData 函数中,获取用户的登录状态,并根据登录状态判断用户是否有权限访问此页面。如果用户未登录,我们可以返回一个 promise,然后在渲染函数执行之后,将 promise.reject 返回的错误对象交给错误处理程序处理,最终跳转到相应的错误页面。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vuecli项目构建SSR服务端渲染的实现 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • Vue Promise的axios请求封装详解

    标题:Vue Promise的Axios请求封装详解 简介:Vue.js 是一款轻量级、渐进式的 JavaScript 框架,提供了数据驱动和组件化的思想,可用于构建任何复杂的单页面应用。而 Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 Node.js。在 Vue.js 开发中,我们常常需要用到 Axios 去请求后台数据。为了…

    Vue 2023年5月28日
    00
  • autojs的Node.js正确退出脚本示例

    AutoJS 是一款安卓设备上运行JavaScript脚本的工具,使用Node.js的方式可以让我们在脚本中使用更多功能,但由于特殊的 Android 平台和 AutoJS 运行环境,在退出脚本时需要注意一些问题。 问题描述 AutoJS 脚本在执行时,如果直接使用 exit() 函数退出,可能会导致脚本未能正确关闭,在下一次运行时会出现在上一次未正常退出后…

    Vue 2023年5月28日
    00
  • 使用异步组件优化Vue应用程序的性能

    当我们使用Vue构建大型应用程序时,组件的加载速度和性能就变得至关重要。Vue的异步组件功能可以帮助我们优化应用程序的性能,让我们来学习如何使用异步组件优化Vue应用程序的性能吧。 什么是异步组件 Vue的异步组件允许我们在构建大型应用程序时通过异步加载组件来提高性能。使用异步组件,我们可以仅在需要时才加载组件,而不是在页面加载时同时加载所有组件。这将加快页…

    Vue 2023年5月27日
    00
  • vue 输入电话号码自动按3-4-4分割功能的实现代码

    实现输入电话号码自动按照 3-4-4 的格式分割,可以通过 Vue 自定义指令实现。以下是具体步骤: 1. 创建自定义指令 在 Vue 中创建自定义指令可以通过 Vue.directive 方法实现。该方法有两个参数,第一个参数是指令名称,第二个参数是指令回调函数。 Vue.directive(‘phone’, { bind: function(el, bi…

    Vue 2023年5月27日
    00
  • JS+HTML实现自定义上传图片按钮并显示图片功能的方法分析

    下面是详细讲解“JS+HTML实现自定义上传图片按钮并显示图片功能的方法分析”的完整攻略。 1. 需求分析 我们的目标是实现在HTML页面中自定义一个上传图片按钮,并且在用户选择上传图片后,能够将图片显示在页面上。 需要具备以下功能: 自定义上传图片按钮 选择图片文件后上传并显示图片 将图片文件转换为base64编码 2. HTML布局 首先,我们需要在HT…

    Vue 2023年5月28日
    00
  • vue使用自定义事件的表单输入组件用法详解【日期组件与货币组件】

    Vue使用自定义事件的表单输入组件用法详解【日期组件与货币组件】 简介 Vue是一种用于构建用户界面的渐进式框架,支持单文件组件,可以非常方便地组合和使用组件来构建应用。自定义表单输入组件可以让开发者轻松地实现与表单的交互,并支持一些常用特性。本篇文档主要介绍如何使用自定义事件来实现日期组件和货币组件,帮助开发者更好地理解自定义表单输入组件的使用方法。 准备…

    Vue 2023年5月28日
    00
  • 详解vue-cli快速构建vue应用并实现webpack打包

    下面是“详解vue-cli快速构建vue应用并实现webpack打包”的完整攻略: 一、安装vue-cli 在终端中输入以下代码安装vue-cli: npm install -g vue-cli 二、创建vue项目 通过以下命令创建一个基于webpack模板的vue项目: vue init webpack myapp 其中,myapp为项目名称,可根据自己的…

    Vue 2023年5月27日
    00
  • vue项目中引入noVNC远程桌面的方法

    以下是详细讲解如何在 Vue 项目中引入 noVNC 远程桌面的方法攻略: 步骤一:安装 noVNC 首先需要安装 noVNC,可以通过命令行使用 npm 安装,具体命令如下: npm install novnc 步骤二:引入 noVNC 打开需要使用 noVNC 的组件文件,例如 Example.vue,在 <script> 标签中引入 noV…

    Vue 2023年5月28日
    00
合作推广
合作推广
分享本页
返回顶部