Nuxt.js 介绍

特性

  • 基于 Vue.js
    • Vue、Vue Router、Vuex、Vue SSR
  • 自动代码分层
  • 服务端渲染
  • 强大的路由功能,支持异步数据
  • 静态文件服务
  • ES2015+语法支持
  • 打包和压缩JS和CSS
  • HTML头部标签管理
  • 本地开发支持热加载
  • 集成ESLint
  • 支持各种样式预处理器: SASS、LESS、Stylus等等
  • 支持 HTTP/2推送

    Nuxt.js框架是如何运作的

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

  • Vue.js

  • Vue Router
  • Vuex
  • Vue Server Renderer

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

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

创建项目

Nuxt提供了两种方式用来创建项目:

  • 使用 create-nuxt-app 脚手架工具
  • 手动创建

本文手动创建
(1)准备

  1. # 创建示例项目
  2. mkdir nuxt-app-demo
  3. # 进入示例项目目录中
  4. cd nuxt-app-demo
  5. # 初始化 package.json 文件
  6. npm init -y
  7. # 安装 nuxt
  8. npm install nuxt

在 package.json 文件的 scripts 中新增

  1. "scripts": {
  2. "dev": "nuxt"
  3. }

通过运行 npm run dev 来运行 nuxt
(2)创建页面并启动项目
创建 pages 目录:

  1. mkdir pages

创建我们的第一个页面 pages/index.vue

  1. <template>
  2. <h1>Hello world!</h1>
  3. </template>

然后启动项目

  1. npm run dev

(3)Nuxt中的基础路由
Nuxt.js会根据pages目录中的所有*.vue文件生成应用的路由配置

Nuxt路由

Nuxt.js依据 pages 目录结构自动生成 vue-router 模块的路由配置

  • 动态路由
    • 在Nuxt.js里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的Vue文件或目录。
  • 嵌套路由

    • 你可以通过 vue-router 的子路由创建 Nuxt.js 应用的嵌套路由。
    • 创建内嵌子路由,你需要添加一个 Vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件。
    • Warning:别忘了在父组件(.vue文件)内增加用于显示子视图内容

      路由配置

  • ttps://zh.nuxtjs.org/docs/2.x/configuration-glossary/configuration-router/

视图
image.png

异步数据——asyncData

  • ttps://zh.nuxtjs.org/guide/async-data
  • asyncData 方法
    • Nuxt.js 扩展了 Vue.js,增加了一个叫”asyncData”的方法,使得我们可以在设置组件的数据之前能异步获取或处理数据
  • 基本用法
    • 它会将asyncData 返回的数据融合组件data方法返回数据一并给组件
    • 调用时机:服务端渲染期间和客户端路由更新之前
  • 注意事项
    • 只能在页面组件中使用
    • 没有 this,因为它是在组件初始化之前被调用的。
  • 上下文对象

    1. async asyncData (context) {
    2. console.log(context)
    3. const { data } = await axios({
    4. method: 'GET',
    5. url" 'http://localhost:3000/data.json'
    6. })
    7. const id = Number.parseInt(context.params.id)
    8. return {
    9. article:data.posts.find(item => item.id === id)
    10. }
    11. }

    生命周期
    image.png
    Vuex 状态管理

  • https://zh.nuxtjs.org/guide/vuex-store

Nuxt 渲染流程
下图阐述了 Nuxt.js 应用一个完整的服务器请求到渲染(或用户通过 切换路由渲染页面)的流程:
image.png
Nuxt常见问题

Nuxt 官方示例

nuxtServerinit

  • 是一个特殊的 action 方法
  • 这个 action 会在服务端渲染期间自动调用
  • 作用:初始化容器数据,传递数据给客户端使用
    ```javascript nuxtServerInit ({ commit }, { req }) { let user = null

    // 如果请求头中有 Cookie if (req.headers.cookie) {

    1. // 使用 cookieparser 把 cookie 字符串转为 JavaScript 对象
    2. const parsed = cookieparser.parse(req.headers.cookie)
    3. try {
    4. user = JSON.parse(parsed.user)
    5. } catch (err) {
    6. // No valid cookie found
    7. }

    }

    // 提交 mutation 修改 state 状态 commit(‘setUser’, user) }

  1. **路由中间件**
  2. - 路由匹配之前先执行中间件
  3. ```javascript
  4. export default {
  5. // 在路由匹配组件渲染之前会先执行中间件处理
  6. middleware: 'authenticated',
  7. name: 'EditorIndex'
  8. }
  • 在项目目录下建立 middleware 文件夹 下建立 authenticated.js

    1. /**
    2. * 验证是否登录的中间件
    3. */
    4. export default function ({ store, redirect }) {
    5. // If the user is not authenticated
    6. if (!store.state.user) {
    7. return redirect('/login')
    8. }
    9. }

    监听 query 参数变化

  • 默认情况下,query的改变不会调用asyncData方法。如果要监听这个行为,例如,在构建分页组件时,您可以设置应通过页面组件的watchQuery属性监听参数。

  • 使用watchQuery属性可以监听参数字符串的更改。 如果定义的字符串发生变化,将调用所有组件方法(asyncData, fetch, validate, layout, …)。 为了提高性能,默认情况下禁用。
  • 如果您要为所有参数字符串设置监听, 请设置: watchQuery: true.

    1. export default {
    2. watchQuery: ['page']
    3. }

    插件

  • https://www.nuxtjs.cn/guide/plugins

  • Nuxt.js 允许您在运行 Vue.js 应用程序之前执行 js 插件。这在您需要使用自己的库或第三方模块时特别有用。
  • 通过插件机制获取到上下文对象(query、params、req、res、app、store…)

    1. // 插件导出函数必须作为 default 成员
    2. export default ({ store }) => {
    3. // 请求拦截器
    4. // Add a request interceptor
    5. // 任何请求都要经过请求拦截器
    6. // 我们可以在请求拦截器中做一些公共的业务处理,例如统一设置 token
    7. request.interceptors.request.use(function (config) {
    8. // Do something before request is sent
    9. // 请求就会经过这里
    10. const { user } = store.state
    11. if (user && user.token) {
    12. config.headers.Authorization = `Token ${user.token}`
    13. }
    14. // 返回 config 请求配置对象
    15. return config
    16. }, function (error) {
    17. // 如果请求失败(此时请求还没有发出去)就会进入这里
    18. // Do something with request error
    19. return Promise.reject(error)
    20. })
    21. }
  • 然后,在 nuxt.config,js 内配置 plugins 如下:

    1. module.exports = {
    2. plugins: ['~/plugins/request.js']
    3. }

    给某个页面加 title

    1. head () {
    2. return {
    3. title: `${this.article.title} - RealWorld`,
    4. meta: [
    5. { hid: 'description', name: 'description', content: this.article.description }
    6. ]
    7. }
    8. }

    发布部署

    基本方法

  • 将应用打包

    1. nuxt build
  • 将打包文件 .nuxt static nuxt.config.js package.json package-lock.json 上传到服务器

    1. scp /path/filename username@servername:/path
  • 在服务器上安装依赖

    1. npm install
  • 在服务器上运行

    1. pm2 start npm -- start

    自动部署

  • 将本地代码提交至 git 仓库

  • 设置 token
    • 目录所在地 Settings —> Developer settings —> Personal access tokens
    • 起一个名称, 勾选第一个选项 repo
    • 得到 token 保存后续使用,这个 token 只出现一次
  • 配置 Secrets
    • 在项目中点击 Settings —> Secrets —> New repository secret
    • 名字 TOKEN 内容: 上一步获得的 token
    • 名字 HOST 内容: 服务器外网 ip
    • 名字 PASSWORD 内容: 服务器密码
    • 名字 PORT 内容: 默认 22
    • 名字 USERNAME 内容: root
  • 项目根目录创建 pm2.config.json

    1. {
    2. "apps": [
    3. {
    4. "name": "RealWorld",
    5. "script": "npm",
    6. "args": "start"
    7. }
    8. ]
    9. }
  • 项目根目录创建.github/workflows/main.yml ```javascript name: Publish And Deploy Demo on: push: tags:

    1. - 'v*'

jobs: build-and-deploy: runs-on: ubuntu-latest steps:

  1. # 下载源码
  2. - name: Checkout
  3. uses: actions/checkout@master
  4. # 打包构建
  5. - name: Build
  6. uses: actions/setup-node@master
  7. - run: npm install
  8. - run: npm run build
  9. - run: tar -zcvf release.tgz .nuxt static nuxt.config.js package.json package-lock.json pm2.config.json
  10. # 发布 Release
  11. - name: Create Release
  12. id: create_release
  13. uses: actions/create-release@master
  14. env:
  15. GITHUB_TOKEN: ${{ secrets.TOKEN }}
  16. with:
  17. tag_name: ${{ github.ref }}
  18. release_name: Release ${{ github.ref }}
  19. draft: false
  20. prerelease: false
  21. # 上传构建结果到 Release
  22. - name: Upload Release Asset
  23. id: upload-release-asset
  24. uses: actions/upload-release-asset@master
  25. env:
  26. GITHUB_TOKEN: ${{ secrets.TOKEN }}
  27. with:
  28. upload_url: ${{ steps.create_release.outputs.upload_url }}
  29. asset_path: ./release.tgz
  30. asset_name: release.tgz
  31. asset_content_type: application/x-tgz
  32. # 部署到服务器
  33. - name: Deploy
  34. uses: appleboy/ssh-action@master
  35. with:
  36. host: ${{ secrets.HOST }}
  37. username: ${{ secrets.USERNAME }}
  38. password: ${{ secrets.PASSWORD }}
  39. port: ${{ secrets.PORT }}
  40. script: |
  41. cd /home/realworld-nuxtjs
  42. wget https://github.com/lipengzhou/realworld-nuxtjs/releases/latest/download/release.tgz -O release.tgz
  43. tar zxvf release.tgz
  44. npm install --production
  45. pm2 reload pm2.config.json
  1. - 将所有代码提交 git 创建 tag 提交
  2. ```javascript
  3. git tag v0.1.0
  4. git push origin v0.1.0
  • 提交成功后在github项目上查看构建状态 Actions
  • 点击 Releases 查看历史版本