使用Nuxt.js框架开发(SSR)服务端渲染项目

2023-11-03

(SSR)服务端渲染的优缺点

优点:

1.前端耗时少,首屏加载速度快。因为后端拼接完了html,浏览器只需要直接渲染出来。

2.有利于SEO。因为在后端有完整的html页面,所以爬虫更容易爬取获得信息,更有利于seo。

3.无需占用客户端资源。即解析模板的工作完全交由后端来做,客户端只要解析标准的html页面即可,这样对于客户端的资源占用更少,尤其是移动端,也可以更省电。

4.后端生成静态化文件。即生成缓存片段,这样就可以减少数据库查询浪费的时间了,且对于数据变化不大的页面非常高效 。

缺点:

1.不利于前后端分离,开发效率低。(无框架前)

2.占用服务器端资源。

即服务器端完成html模板的解析,如果请求较多,会对服务器造成一定的访问压力。而如果使用前端渲染,就是把这些解析的压力分摊了前端,而这里确实完全交给了一个服务器。

# Nuxt.js起源

2016 年 10 月 25 日, zeit.co 背后的团队对外发布了 Next.js ,一个 React 的服务端渲染应用框架。几小时后,与 Next.js 异曲同工,一个基于 Vue.js 的服务端渲染应用框架应运而生,我们称之为:Nuxt.js。

Nuxt 是服务器呈现的简约应用程序的框架,通过对客户端和服务端基础架构的抽象,Nuxt.js 可以让开发者更专注于页面的UI渲染。作用就是在 node.js 上进一步封装,然后省去我们搭建服务端环境的步骤,只需要遵循这个库的一些规则就能轻松实现 SSR。

作用及特性

  • 通过对客户端/服务端基础架构的抽象组织,Nuxt.js 主要关注的是应用的 UI 渲染
  • Nuxt.js 预设了利用 Vue.js 开发服务端渲染的应用所需要的各种配置。
  • 支持 Vue.js 应用的静态化,通过 nuxt generate 命令实现。
  • 基于 Vue.js
  • 自动代码分层
  • 服务端渲染
  • 强大的路由功能,支持异步数据
  • 静态文件服务
  • ES2015+ 语法支持
  • 打包和压缩 JS 和 CSS
  • HTML 头部标签管理
  • 本地开发支持热加载
  • 集成 ESLint
  • 支持各种样式预处理器:SASS、LESS、Stylus 等等
  • 支持 HTTP/2 推送

核心原理

 

图片

 

 

Nuxt.js 集成了以下组件/框架,用于开发完整而强大的 Web 应用:

压缩并 gzip 后,总代码大小为:57kb (如果使用了 Vuex 特性的话为 60kb)。

另外,Nuxt.js 使用 Webpack 和 vue-loader 、 babel-loader 来处理代码的自动化构建工作(如打包、代码分层、压缩等等)。

work flow:

 

图片

 

安装(略)

详见 zh.nuxtjs.org/guide/insta…

目录结构

├── assets           //用于组织未编译的静态资源如 LESS、SASS 或 JavaScript
│   └── README.md
├── components       //用于组织应用的 Vue.js 组件。Nuxt.js 不会扩展增强该目录下 Vue.js 组件,即这些组件不会像页面组件那样有 asyncData 方法的特性
├── layouts    //布局目录 layouts 用于组织应用的布局组件。若无额外配置,该目录不能被重命名。
│   ├── README.md
│   └── default.vue
├── middleware    //目录用于存放应用的中间件
│   └── README.md
├── nuxt.config.js  //nuxt 配置文件
├── pages           //放page页面,自动生产路由
│   ├── README.md
│   ├── index.vue
│ 
├── plugins    //用于组织那些需要在 根vue.js应用 实例化之前需要运行的 插件
│   ├── README.md
│   └── axios.js
├── server                
│   └── index.js           //服务配置
├── static           
│   ├── README.md     //存放静态文件,不被编译
│   ├── favicon.ico
│   ├── icon.png
│   └── sw.js
├── store                 //vuex状态
│   ├── README.md
│   ├── index.js
│   └── webLogin.js
复制代码

 

常用 API

生命周期

Nuxt扩展了Vue的生命周期

export default {
  middleware (ctx) {}, //服务端
  validate (ctx) {}, // 服务端
  asyncData (ctx) {}, //服务端
  fetch (ctx) {}, // store数据加载
  beforeCreate () {  // 服务端和客户端都会执行},
  created () { // 服务端和客户端都会执行 },
  beforeMount () {}, 
  mounted () {} // 客户端
}
复制代码

 

context 对象

context 的可用属性一览:

属性字段 类型 可用 描述
app Vue 根实例 客户端 & 服务端 包含所有插件的 Vue 根实例。例如:在使用 axios 的时候,你想获取 axios 可以直接通过 context.app.axios 来获取
isClient Boolean 客户端 & 服务端 是否来自客户端渲染(废弃。请使用 process.client )
isServer Boolean 客户端 & 服务端 是否来自服务端渲染(废弃。请使用 process.server )
isStatic Boolean 客户端 & 服务端 是否来自 nuxt generate 静态化(预渲染)(废弃。请使用 process.static )
isDev Boolean 客户端 & 服务端 是否是开发 dev 模式,在生产环境的数据缓存中用到
isHMR Boolean 客户端 & 服务端 是否是通过模块热替换 webpack hot module replacement (仅在客户端以 dev 模式)
route Vue Router 路由 客户端 & 服务端 Vue Router 路由实例
store Vuex 数据 客户端 & 服务端 Vuex.Store 实例。只有vuex 数据流存在相关配置时可用
env Object 客户端 & 服务端 nuxt.config.js 中配置的环境变量,见 环境变量 api
params Object 客户端 & 服务端 route.params 的别名
query Object 客户端 & 服务端 route.query 的别名
req http.Request 服务端 Node.js API 的 Request 对象。如果 Nuxt 以中间件形式使用的话,这个对象就根据你所使用的框架而定。nuxt generate 不可用
res http.Response 服务端 Node.js API 的 Response 对象。如果 Nuxt 以中间件形式使用的话,这个对象就根据你所使用的框架而定。nuxt generate 不可用
redirect Function 客户端 & 服务端 用这个方法重定向用户请求到另一个路由。状态码在服务端被使用,默认 302 redirect([status,] path [, query])
error Function 客户端 & 服务端 用这个方法展示错误页:error(params) 。params 参数应该包含 statusCode 和 message 字段
nuxtState Object 客户端 Nuxt 状态,在使用 beforeNuxtRender 之前,用于客户端获取 Nuxt 状态,仅在 universal 模式下可用
beforeNuxtRender(fn) Function 服务端 使用此方法更新 NUXT 在客户端呈现的变量,fn 调用 (可以是异步) { Components, nuxtState } ,参考 示例

 

asyncData 函数

  • **类型:**Function

asyncData 方法会在组件(限于页面组件)每次加载之前被调用。它可以在服务端或路由更新之前被调用。在这个方法被调用的时候,第一个参数被设定为当前页面的上下文对象,你可以利用 asyncData 方法来获取数据并返回给当前组件。

export default {
  data () {
    return { project: 'default' }
  },
  asyncData (context) {
    return { project: 'nuxt' }
  }
}
复制代码

注意:由于 asyncData 方法是在组件 初始化 前被调用的,所以在方法内是没有办法通过 this 来引用组件的实例对象。

fetch 函数

fetch 方法用于在渲染页面前填充应用的状态树(store)数据, 与 asyncData 方法类似,不同的是它不会设置组件的数据。

  • **类型:**Function

如果页面组件设置了 fetch 方法,它会在组件每次加载前被调用(在服务端或切换至目标路由之前)。

fetch 方法的第一个参数是页面组件的 上下文对象 context,我们可以用 fetch 方法来获取数据填充应用的vuex状态树。为了让获取过程可以异步,你需要返回一个 Promise,Nuxt.js 会等这个 promise 完成后再渲染组件。

警告: 您无法在内部使用 this 获取组件实例,fetch 是在组件初始化之前被调用

例如 pages/index.vue:

<template>
  <h1>Stars: {{ $store.state.stars }}</h1>
</template>
<script>
export default {
  fetch ({ store, params }) {
    return axios.get('http://my-api/stars')
    .then((res) => {
      store.commit('setStars', res.data)
    })
  }
}
</script>
你也可以使用 async 或 await 的模式简化代码如下:
<template>
  <h1>Stars: {{ $store.state.stars }}</h1>
</template>
<script>
export default {
  async fetch ({ store, params }) {
    let { data } = await axios.get('http://my-api/stars')
    store.commit('setStars', data)
  }
}
</script>
复制代码

如果要在 fetch 中调用并操作 store,请使用 store.dispatch,但是要确保在内部使用 async / await 等待操作结束:

<script>
export default {
  async fetch ({ store, params }) {
    await store.dispatch('GET_STARS');
  }
}
</script>
store/index.js
// ...
export const actions = {
  async GET_STARS ({ commit }) {
    const { data } = await axios.get('http://my-api/stars')
    commit('SET_STARS', data)
  }
}
复制代码

监听 query 字符串的改变 默认情况下,不会在查询字符串更改时调用 fetch 方法。如果想更改此行为,例如,在编写分页组件时,您可以设置通过页面组件的 watchQuery 属性来监听参数的变化。了解更多有关 API watchQuery page 的信息。

增加用户体验的两个插件

@nuxtjs/toast模块

toast可以说是很常用的功能,一般的UI框架都会有这个功能。但如果你的站点没有使用UI框架,而alert又太丑,不妨引入该模块:

npm install @nuxtjs/toast
复制代码

然后在nuxt.config.js中引入

module.exports = {
    modules: [
    '@nuxtjs/toast',
    ['@nuxtjs/dotenv', { filename: '.env.prod' }] // 指定打包时使用的dotenv
  ],
  toast: {// toast模块的配置
    position: 'top-center', 
    duration: 2000
  }
}
复制代码

这样,nuxt就会在全局注册$toast方法供你使用,非常方便:

this.$toast.error('服务器开小差啦~~')
this.$toast.error('请求成功~~')
复制代码

loading方法

nuxt内置了页面顶部loading进度条的样式 推荐使用,提供页面跳转体验。

//打开
this.$nuxt.$loading.start() 
//完成 
this.$nuxt.$loading.finish()
复制代码

更多 API 详见官网 zh.nuxtjs.org/api

源码浅析

源码地址:github.com/nuxt/nuxt.j…

源码目录:

 

图片

 

 

1、通过 .nuxt 文件来执行我们的工作流程

 

图片

 

 

这个是我们项目生成的临时文件,我们项目运行时候配置的文件都是在这里,大家可以看到这里的路由文件,没错,这个就是系统自动给我们配置的路由文件,根据我们的 pages 文件夹路径生成的,大家还可以看到,由app.js ,client.js 和 server.js 这两个就是类似我们的 SSR 中配置的那个 server.js 入口文件,然后还有 middleware.js 中间件文件,其实这个时候我们大概能懂了,上边我们说的工作流程,走的就是这个 临时文件.nuxt 文件夹中的内容,但是这个文件夹是如何生成的呢,大家请往下看。

2、.nuxt 是如何产生的

本文主要研究nuxt的运行原理,分析它从接收一条nuxt指令,到完成指令背后所发生的一系列事情,在开始本文之前,请读者务必亲自体验过nuxt.js的使用,并且具备一定的vue.js相关开发经验。

通过查看nuxt.js工程目录下的package.json文件,我们可以看到下列几条指令:

"scripts": { "dev": "nuxt",           // 开启一个监听3000端口的服务器,同时提供hot-reloading功能
    "build": "nuxt build", //构建整个应用,压缩合并JS和CSS文件(用于生产环境)
    "start": "nuxt start", // 开启一个生产模式的服务器(必须先运行nuxt build命令)
    "generate": "nuxt generate" //构建整个应用,并为每一个路由生成一个静态页面(用于静态服务器)
} 
复制代码

咱们还从来没有看过我们的依赖包哈,今天就来看看,打开我们的 node_modules 文件夹下的 nuxt工程文件夹 进入到到bin目录,我们可以看到几个文件:

 

图片

 

 

咱们就说一下 dev 是如何工作的,咱们先找到一个片段,发现基本是执行了以下几个步骤:

  async run (cmd) {
    const { argv } = cmd
    await this.startDev(cmd, argv, argv.open)
  },

  async startDev (cmd, argv) {
    let nuxt
    try {
      nuxt = await this._listenDev(cmd, argv)
    } catch (error) {
      consola.fatal(error)
      return
    }
    try {
      await this._buildDev(cmd, argv, nuxt)
    } catch (error) {
      await nuxt.callHook('cli:buildError', error)
      consola.error(error)
    }
    return nuxt
  },
复制代码

 

图片

 

 

那什么是 nuxt() 类,它又是执行了什么样的方法呢?

 

图片

 

 

上图中每一步都可以在具体的代码中自行浏览。在用户输入指令并实例化了Nuxt()类以后,实例化

同时,Nuxt()类也提供了一个close()公有方法,用于关闭其所开启的服务器。

3、builder.build() 进行编译

 

图片

 

 

简单来说,build()方法在判断完运行条件后,会先初始化产出目录.nuxt,然后通过不同目录下的文件结构来生成一系列的配置,写入模板文件后输出到.nuxt目录。接下来,则会根据不同的开发环境来调用不同的webpack配置,运行不同的webpack构建方案。

4、render.js文件 打包输出渲染

在nuxt/lib目录下找到render.js文件,它包含着我们即将要分析的三个方法:render(), renderRoute(), renderAndGetWindow()。

 

图片

 

 

通过这张图片,我们可以知道nuxt对于处理“客户端渲染”与“服务端渲染”的逻辑其实是非常清晰的。

  • 首先,在render()方法在处理完一系列的路径问题后,会调用renderRoute()方法,获取响应所需内容并完成响应。
  • 其中renderRoute()方法会判断当前响应是否应执行服务端渲染。如果是,则调用vue提供的bundleRenderer()方法,把html内容渲染完毕以后再整体输出;如果不是,则直接输出一个字符串,交由客户端渲染。
  • 最后,通过renderAndGetWindow()来检查输出的html是否存在问题,然后发出通知,表明html可用。

打包部署

上传全部代码到自己到服务器上执行 编译打包:

npm run build
npm run start
复制代码

建议部署方式Docker+K8S

------------------------------------个人项目-----------------------------------

项目介绍

  • 项目地址:www.ffbig.cn/ 项目来源于博主自己的职业生涯技能总结和梳理,内容在不断充实中。 全栈大前端系列总共分为 3 期:
  • 1 期梳理基础知识和常用技术栈
  • 2 期学习跨端融合技术认识"大前端"
  • 3 期结合服务端技术通晓 "全栈"

项目大纲

 

 

 

如果你发现本项目有内容上的错误,欢迎提交 issues 进行指正。

学习交流

建了一个“全栈大前端”的微信交流群,欢迎纯粹技术交流爱好者加入!

 


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用Nuxt.js框架开发(SSR)服务端渲染项目 的相关文章

  • JVM-监控及诊断工具

    本文目录 命令行 jps 查看正在运行的Java进程 jstat 查看JVM统计信息 jinfo 实时查看和修改JVM配置参数 jmap 导出内存映像文件 内存使用情况 jhat JDK自带堆分析工具 jstack 打印JVM中线程快照 j
  • 题目爬取 js

    function collect 内容元素 const content document querySelector content 题目正则 const regexp d 题 n s S 参考答案 A Z 选项正则 const optio
  • Vue3实现Pagination分页组件(一)基础实现

    转载于 Vue3实现Pagination分页组件 一 基础实现 掘金 写在前面 在 B 端的 web 开发中 分页组件或者叫分页器 是较为常用的控件之一 通常配合表格或列表 实现数据量大的情况下 分页拆解数据的功能 由于完整实现的篇幅较大
  • 用c语言编写gps程序,GPS模拟C语言

    A 7654321 B 1714171 C 1711717 D 7177171 48 以下程序的输出是 C include main char a language p p a while p u printf c p u U p A LA
  • 【华为OD机试真题2023B卷 JAVA&JS】采样过滤

    华为OD2023 B卷 机试题库全覆盖 刷题指南点这里 采样过滤 知识点滑窗 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 在做物理实验时 为了计算物体移动的速率 通过相机等工具周期性的采样物体移动距离 由于工具故障 采样

随机推荐

  • 【C语言】求任意两整数的和入门详解

    今天我们来看这个使用c语言编写的一个简易的求和程序 代码如下 define CRT SECURE NO WARNINGS 1 该行代码用来解决scanf函数报错的 不推荐使用scanf s来修正 因为该解决方案并非适用于所有编译器 incl
  • 极坐标转化

    在数学中 极坐标系是一个二维坐标系统 该坐标系统中任意位置可由一个夹角和一段相对原点 极点的距离来表示 极坐标系的应用领域十分广泛 包括数学 物理 工程 航海 航空以及机器人领域 两点间的关系用夹角和距离很容易表示时 极坐标系便显得尤为有用
  • Spring课件

    容器与 bean 1 容器接口 BeanFactory 接口 典型功能有 getBean ApplicationContext 接口 是 BeanFactory 的子接口 它扩展了 BeanFactory 接口的功能 如 国际化 通配符方式
  • Python自动化

    usr bin env python os system gnome terminal e bash c ls exec bash coding utf 8 import linecache import pyautogui import
  • Nginx(代理)+Tomcat(Java)+Apache(PHP)共用80端口

    解决的核心问题是 使用一个80端口 根据域名或者子域名 同时访问java php运行环境 1 下载nginx 官网下载链接 http nginx org en download html 接下来我以nginx Windows 1 16 0
  • 『学Vue2+Vue3』智慧商城项目

    智慧商城 接口文档 https apifox com apidoc shared 12ab6b18 adc2 444c ad11 0e60f5693f66 doc 2221080 演示地址 http cba itlike com publi
  • 在ubuntu下安装vscode

    ubuntu22 04下通过命令安装vscode 1 为什么不用应用市场直接下载 最近下载ubuntu22 04版本 不知道为啥里面的应用软件下载不了vscode 尝试在网上解决 gt 卸载自带的应用市场 安装另外的一种 结果失败了 导致原
  • 【路由指令】

    一 linux route add net 192 0 0 0 netmask 255 0 0 0 gw 192 180 30 1 sudo route add net 192 180 0 0 netmask 255 255 0 0 gw
  • python爬取今日头条后台数据_爬虫爬取今日头条数据代码实现

    课程链接 讲师的公众号文章 今日头条数据抓取及持久化 完整代码版 含IP和用户代理 mp weixin qq com 课程代码 抓取并持久化user agent工具utils py 对于爬虫工具 需要设置发起请求的user agent im
  • Spring Boot 框架基础

    Spring Boot 框架基础 基础案例 pom xml
  • BUCK LX_OUT Snubber电路

    1 问题 开关节点振铃 过冲 开关节点过冲会导致LX OUT管脚的电压过高 如果超过datasheet上的maximum值 就有可能影响DCDC芯片寿命 2 产生振铃 过冲的原因 2 1 输入电容摆放不正确 2 2 输出电感 电容摆放不正确
  • STM32F103滴答计时器之delay函数

    如果使用FreeRTOS void delay us u32 nus u32 ticks u32 told tnow tcnt 0 u32 reload SysTick gt LOAD ticks nus fac us tcnt 0 del
  • k8s删除deployment_k8s灾备指南(Velero)

    最近验证了使用velero对k8s进行灾难恢复 操作验证步骤如下 1 下载verlero 解压 tar xvf
  • java案例15:模拟订单号生成

    思路 模拟订单号生成 超市购物时 小票上都会有一个订单号 且订单号唯一 编写程序模拟订单系统中订单号的生成 生成订单号时 使用年月日和毫秒值组合生成唯一订单号 例如 给一个包括年月日和毫秒值的数组arr 2023 0401 1100 将其拼
  • git解决代码冲突、合并代码

    共同开发时提交代码会遇到代码冲突 第一次遇到就手足无措的我 打算写一篇博客记录下来 下次遇到稳如老狗 一 远程代码已有更新记录 忘记拉取远程代码 直接提交 单人开发时 我没有先拉远程代码再提交的习惯 千万不要学习 一定要先拉代码再提交 导致
  • 关于odoo条码显示问题处理

    这里分几种情况 1 第一种情况 打印的单据不显示条码 这种情况比较常见 一般是 没有对应字体导致 不能正常显示条码 单据打印的条码 一片空白 无条码的情况 这种情况是因为 条码的字体没有安装 需要安装一下 这里我会把资源上传 大家可以下载
  • Mac texlive+texstudio 如何手动安装宏包

    1 从CTAN上搜索自己需要的package 2 以subfigure为例 选择第一个结果 下载下来 3 解压下载后的文件 这时候发现里面并没有 sty文件 在终端中输入latex subfigure即可生成需要的sty文件 将整个文件夹保
  • nuxt.js-------koa2项目,环境错误一次性解决

    nuxt js虽然好用但是自己的脚手架安装完全是坑 cnpm run dev 报错确实main js node环境nuxt版本不匹配 在网上找了很多解决方法没有解决 就一次性把所有脚手架和环境都升级到最新版本 npm install bac
  • Nginx 负载均衡 - fair

    学习在 Nginx 中使用 fair 模块 第三方 来实现负载均衡 fair 采用的不是内建负载均衡使用的轮换的均衡算法 而是可以根据页面大小 响应时间智能的进行负载均衡 1 准备工作 nginx upstream fair 官方下载地址
  • 使用Nuxt.js框架开发(SSR)服务端渲染项目

    SSR 服务端渲染的优缺点 优点 1 前端耗时少 首屏加载速度快 因为后端拼接完了html 浏览器只需要直接渲染出来 2 有利于SEO 因为在后端有完整的html页面 所以爬虫更容易爬取获得信息 更有利于seo 3 无需占用客户端资源 即解