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

下面是关于“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日

相关文章

  • vue3 Vite 进阶rollup命令行使用详解

    针对“vue3 Vite 进阶rollup命令行使用详解”的主题,我将为您提供一份完整的攻略。如下: 什么是Vue3 Vite? Vue3 Vite 是 Vue.js 团队开发的一款基于本地开发服务器和源码构建的新型前端构建工具。它旨在提供快速的开发环境和简单易懂的打包机制。 什么是Rollup? Rollup 是一种 JavaScript 模块打包器。它基…

    Vue 2023年5月28日
    00
  • 简单学习5种处理Vue.js异常的方法

    下面我将详细讲解“简单学习5种处理Vue.js异常的方法”的完整攻略。 异常处理 在Vue.js应用中,异常处理是一个必不可少的部分。因为在应用的运行过程中,难免会出现一些错误或者异常情况,需要进行合理的处理。 常见的异常 TypeError:类型不匹配,通常发生在访问null或undefined值或者使用对象上不存在的方法或属性时。 ReferenceEr…

    Vue 2023年5月27日
    00
  • Vue 中 createElement 使用实例详解

    下面我给出“Vue 中createElement 使用实例详解”的完整攻略,包括基本语法和两条示例说明。 What is createElement? createElement 是 Vue 的一个渲染函数,它通过 JavaScript 代码的方式生成虚拟 DOM。通过 createElement 我们能够在 JS 代码中定义 Vue 的组件,从而实现动态渲…

    Vue 2023年5月29日
    00
  • Uniapp微信小程序实现全局事件监听并进行数据埋点的方法

    Uniapp是一款使用Vue框架的跨平台开发框架,可以快速创建小程序、APP等项目。在开发小程序时,我们可能需要对用户的行为进行监控和数据统计,这就需要实现全局事件监听并进行数据埋点。下面就是Uniapp微信小程序实现全局事件监听并进行数据埋点的方法的攻略: 一、引用埋点SDK 我们可以使用统计分析平台提供的埋点SDK来实现数据埋点。以CNZZ为例,CNZZ…

    Vue 2023年5月27日
    00
  • vue实现钉钉的考勤日历

    下面是详细讲解“vue实现钉钉的考勤日历”的完整攻略。 1. 需求分析 首先,我们需要明确实现钉钉考勤日历的需求,包括数据展示、日期筛选、数据搜索等功能,然后根据需求选择合适的UI组件和数据处理方式。 2. 数据处理 接下来,我们需要对考勤数据进行处理,包括读取本地文件、筛选数据、统计数据等,并将处理后的数据渲染到页面上。 3. UI组件选择 根据需求,我们…

    Vue 2023年5月28日
    00
  • Vant 中的Toast设置全局的延迟时间操作

    下面我为您讲解如何在 Vant 中设置全局的 Toast 延迟时间。 首先,让我们看一下 Vant 中 Toast 组件的默认配置: const defaultOptions = { type: ‘text’, mask: false, message: ”, duration: 3000, className: ”, iconClass: ”, on…

    Vue 2023年5月29日
    00
  • 聊聊Javascript中try catch的2个作用

    标题:聊聊JavaScript中try catch的2个作用的完整攻略 首先,在JavaScript中,try-catch语句是一种错误处理机制。try块中的代码将被执行,如果出现异常或错误,catch块中的代码将被捕获并执行。在JavaScript中,try-catch语句有两个主要的作用。 作用一:捕获并处理异常 try-catch语句最常用的作用是用来…

    Vue 2023年5月28日
    00
  • vue中如何简单封装axios浅析

    下面是详细讲解”Vue中如何简单封装Axios浅析”的攻略,包含以下内容: 1. 简单介绍Axios Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。它是一个非常流行的、简单易用的 HTTP 请求库,非常适用于 Vue.js 中进行数据请求。 2. 封装 Axios 的目的 在 Vue.js 项目中,我们不可能…

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