Nuxt学习_基础知识(二)

文章学习来源,nuxt中文网

1. 异步数据 AsyncData

1.1 获取并返回数据

AsyncData:在设置组件之前能异步获取或处理数据。async方法会在页面组件每次加载之前调用(没有this),可以在服务端或路由更新之前调用。在这个方法调用的时候,第一个参数被设定为当前页面的上下文对象,可以利用asyncData方法来获取数据,nuxt.js会将asyncData返回的数据融合组件data返回的数据一并返回给当前组件。

在详情页面使用asyncData调用并返回数据:
pages/detail/_id.vue

export default Vue.extend({
	  asyncData({params}) {
	    console.log(params, '当前params指代的是什么内容') // params指代路径参数,比如详情页面路径上的id
	    return axios.get('http://127.0.0.1:8090/api/fruits').then(({data}) => {
	      console.log(data.dataSource, '返回结果') // 接口返回值
	      return {
	        list: data.dataSource // return中返回的值和设置的属性,会合并到data中
	      }
	    })
  	},
})
  • 可以通过Promise、async/await、callback方式来处理返回值,以上述为例,通过Promise方式调用接口return一个属性,属性的值为对应接口的值,这个属性和值会同时被合并到data中,在页面加载完成后即可使用

1.2 处理异步请求

当发起网络请求时,我们通常可能需要对headers中增加信息进行校验,也可能需要对返回的response信息进行处理,可以通过进行封装Axios,增加拦截器来进行处理

  • 封装自己的带有拦截器的Axios request/index.js
import axios from "axios";
const myAxios = axios.create({
  baseURL: 'http://127.0.0.1:8090/api'
})

myAxios.interceptors.request.use(
  (req) => {
    req.headers.Authorization = 'XXX' // 在headers中增加信息进行校验等...
    return req
  }
)
myAxios.interceptors.response.use(
  (res) => {
    return {
      data: res.data
    }
  }, // 正确返回时处理response返回至
  (err) => {
    console.log(err)
    // return Promise.reject(err)
  } // 发生错误时,处理错误信息
)
export default myAxios

  • 在页面使用封装拦截后的Axios
import myAxios from "~/request";

  async asyncData() {
    try {
      let { data } = await myAxios.get('http://127.0.0.1:8090/api/fruits')
      return {
        list: data.dataSource || []
      }
    }catch (err) {
      console.log(err.message)
      // alert(err.message)
    }
  },

2. 插件

2.1 注入Vue实例

若有需要用到相关的插件,在vue.js执行前进行执行,比如Toast组件,要做到以下几步

2.1.1 自定义Toast插件

components/Toast.vue

<template>
  <transition name="fade">
    <div v-if="visible" class="toast">
      {{ message }}
    </div>
  </transition>
</template>

<script>
export default {
  data() {
    return {
      visible: false,
      message: ''
    };
  },
  methods: {
    show(msg, duration = 2000) {
      this.message = msg;
      this.visible = true;
      setTimeout(() => {
        this.visible = false;
      }, duration);
    }
  }
};
</script>

<style scoped>
.toast {
  width: 200px;
  height: 100px;
  border-radius: 36px;
  background-color: green;
  color: blue;
  position: fixed;
  left: 50%;
  top: 40px;
  transform: translateX(-50%);
  z-index: 2;
  display: flex;
  justify-content: center;
  align-items: center;
}

.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to /* .page-leave-active 在 <2.1.8 版本中 */ {
  opacity: 0;
}
</style>

2.1.2 声明插件

plugins/toast.js

import Vue from 'vue';
import Toast from '~/components/Toast.vue';

const ToastConstructor = Vue.extend(Toast);
const instance = new ToastConstructor();

// 将实例挂载到body上
instance.$mount(document.createElement('div'));
document.body.appendChild(instance.$el);

// 注入到Vue原型上
Vue.prototype.$toast = (msg, duration) => {
  instance.show(msg, duration);
};

2.1.3 配置插件

nuxt.config.js

export default {
  plugins: [
    '~/plugins/toast.js'
  ],
}

2.1.4 页面使用

this.$toast(`Hello 用户${this.currentId}`, 1000)

2.2 注入$root和context

在2自定义插件中,我们将Toast注入Vue实例,通过$toast在Vue组件中进行使用这个函数,除此之外,我们还可以注入context

2.2.1 注入context

context注入也是plugins插件中的一种,我们可以在context上面定义一些方法,比如说是一些通用的公共的方法,在每一次需要context以及这个方法时直接调用,而不用重复写多次代码

  • plugins/ctx-inject.js
export default ({ app }, inject) => {
  app.myInjectedFunction = (string) => { // 可以传参
    console.log(app, 'app是什么') // Vue实例
    console.log(inject, 'inject是什么') // inject方法
    console.log('Okay, another function', string) // 定义某种具体的操作
  }
}
  • nuxt.config.js
  plugins: [
    '~/plugins/ctx-inject.js',
  ],
  • 页面使用 xx.vue
  async asyncData(context) {
    context.app.myInjectedFunction('use context 注入')
  }

2.3 同时注入

上述2.2注入context的方式只限于在使用上下文时进行使用,如果我们想在context、Vue实例甚至是Vuex中同时注入,我们可以依然可以通过inject方法来实现一个更加完美的方式

  • plugins/combine-inject.js
export default ({ app }, inject) => {
  inject('myCombineInjectFunction',  params => console.log('Okay, this combine inject', params))
}
  • nuxt.config.js 中配置
  plugins: [
    '~/plugins/combine-inject.js'
  ],
  • xx.vue 页面中使用
async asyncData(context) {
	context.app.$myCombineInjectFunction('context中混合注入') // 注意,此处与context的区别是function前面增加了$符号
}

  mounted() {
    this.$myCombineInjectFunction('mounted中混合注入') // store中用法与此处相同
  }

3. 模块

模块是Nuxt.js的扩展,可以扩展其核心功能并添加无限的集成。Nuxt 可以使用配置选项和插件进行扩展,但是在多个项目中维护这些自定义是繁琐、重复和耗时的。 我们可以使用功能强大的 Hookable Nuxt.js 系统来完成特定事件的任务。Nuxt 模块可以合并到 npm 包中

3.1 基本模块

模块只是简单的功能,可以打包为npm模块或直接包含在项目源代码中

  • 定义modules/my-nuxt-module/index.js
export default function (moduleOptions = {}) {
  // 你可以在这里添加插件、中间件、服务器端中间件等
  // 例如,添加一个简单的插件
  this.nuxt.hook('build:before', () => {
    console.log('Nuxt build is starting...'); // 在build时打印在terminal上
  });

  // 添加单个插件
  // this.addPlugin({
  //   src: '~/plugins/combine-inject.js', // 注意这里的路径是相对于 Nuxt 项目的根目录
  //   ssr: false, // 如果插件只在客户端运行,设置为 false
  // });

  // 添加多个插件
  this.nuxt.options.plugins.push(
    { src: '~/plugins/combine-inject.js', ssr: true },
    { src: '~/plugins/ctx-inject.js', ssr: false },
  )
}

// 你可以在这里导出模块元数据(可选)  若想要发布到npm上面,这一步骤是必须的
module.exports.meta = require('../../package.json');

  • 在nuxt.config.js中应用该modules
export default {
  modules: [
    // 引入自定义模块
    '~/modules/my-nuxt-module'
  ],
}
  • this代表module中的context
  • this.options可以直接访问nuxt选项,这是nuxt.config.js,其中包含所有默认选项,可用于模块之间的共享选项。
  • this.nuxt, 对当前nuxt实例的引用
  • module.export.meta 模块发布npm必须选项

3.2 异步模块

并不是所有模块都能同步完成全部操作,比如我们会需要获取某些API或执行异步IO操作的模块,Nuxt支持在异步模块中返回Promise或调用回调

  • async/await方式

modules/async-module.js

import fse from 'fs-extra'
export default async function() {
  const pages = await fse.readJson('../../package.json')
  console.log(pages, '读取到的内容有哪些')    // 打印读取了package.json中的内容
}

nuxt.config.js

export default {
	modules: [
		'~/modules/async-module'
	]
}
  • promise方式
import axios from 'axios'

export default function asyncModule() {
  return axios
    .get('https://jsonplaceholder.typicode.com/users')
    .then(res => res.data.map(user => '/users/' + user.username))
    .then(routes => {
      // Do something by extending Nuxt routes
    })
}

4. 插件与模块的异同

模块与插件是两种用于扩展nuxt应用功能的方式

4.1 共同点

  • 扩展性: 无论模块还是插件,都是为了增加nuxt应用的功能而设计的,使得开发者能够根据自己的需求进行扩展
  • 可重用性:两者都支持被封装成独立的单元,以便于在多个项目中重复使用

4.2 不同点

  • 定义与用途

    • 模块:模块是nuxt的扩展,可以扩展nuxt的核心功能并添加新的集成。模块通常包含一系列预定义的配置和钩子,用于在nuxt应用的生命周期中注入额外的功能和逻辑。它可以在nuxt.config.js中被引入和配置
    • 插件通常用于向Vue组件中注入全局属性和方法,或者添加Vue实例的混入等,插件需要在nuxt的插件系统中注册,以便在应用启动时加载
  • 加载时机

    • 模块: 模块在nuxt应用启动时加载,并按照在nuxt.config.js中声明的顺序执行,它们可以在nuxt的生命周期中的不同阶段注入代码,从而影响应用的构建、渲染等过程
    • 插件:插件通常在Vue应用实例创建之前被加载,并可以访问到Vue上下文(如Vue实例,Vuex store等)。这使得插件能够在Vue组件初始化之前,向Vue实例中添加全局方法、混入等
  • 作用域

    • 模块: 模块的作用域相对较广,可以影响nuxt应用的各个方面,如路由、Vuex、组件等,模块通常通过Nuxt的生命周期钩子来实现其功能。
    • 插件:插件的作用域更关注与Vue组件和Vue实例,它们主要用于向Vue组件中注入全局的功能和属性,以便在组件内部使用
  • 使用方式:

    • 模块:在nuxt.config.js文件中,通过modules数组引入模块,并且可以传递配置选项给模块
    • 插件:在Nuxt的插件目录中创建插件文件,然后在nuxt.config.js中plugins数组中注册插件。插件可以是一个JavaScript文件,也可以是一个对象,用于定义插件的源文件、模式(如客户端或服务器端)等选项。

注意事项

  • 默认情况下 Nuxt 使用 vue-loader、file-loader 以及 url-loader 这几个 Webpack 加载器来处理文件的加载和引用。对于不需要通过 Webpack 处理的静态资源文件,可以放置在 static 目录中。需要处理的可以放到 assets 目录。
  • 在任何 Vue 组件的生命周期内, 只有 beforeCreate 和 created 这两个方法会在 客户端和服务端被调用。其他生命周期函数仅在客户端被调用。
  • 注意nuxt 与 nuxt start并不是相同的指令,在使用时不同的指令有不同的先决条件,不要用错

如果有用,点个赞呗~

总结用法,希望可以帮助到你,
我是Ably,你无须超越谁,只要超越昨天的自己就好~

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值