编写 Nuxt 模块
模块本质上是一个在 Nuxt
启动时执行的顶级 JavaScript
函数。 Nuxt
会按顺序调用每个模块,并等待所有模块执行完毕后再继续调用 Vue
实例、Vue
插件以及需要注入到 $root
和 Nuxt
上下文中的全局函数。由于模块的调用时机早于它们(如 Vue
实例等),我们可以利用模块来覆盖模板、配置 webpack
加载器、添加 CSS
库或执行应用所需的其他任务。此外,模块还能打包为 npm
包并与 Nuxt
社区共享。可通过以下链接查看 Nuxt
社区提供的生产级模块: https://github.com/nuxt-community/awesome-nuxt#official
现在让我们尝试使用 Axios
模块——这是一个为 Nuxt
集成 Axios
( https://github.com/axios/axios )的模块。它自带诸如自动设置客户端和服务端基础 URL
等功能,后续章节将探索其部分特性。若需深入了解该模块,请访问 https://axios.nuxtjs.org/ 。以下是具体使用步骤:
-
通过
npm
安装:$ npm install @nuxtjs/axios
-
在
Nuxt
配置文件中配置:// nuxt.config.js module.exports = { modules: [ '@nuxtjs/axios' ] }
-
在任意位置使用,例如页面的
asyncData
方法中:// pages/index.vue async asyncData({ $axios }) { const ip = await $axios.$get('http://icanhazip.com') console.log(ip) }
也可在
mounted
方法(或created
、updated
等)中使用:// pages/index.vue async mounted() { const ip = await this.$axios.$get('http://icanhazip.com') console.log(ip) }
每当访问 /about
页面时,浏览器控制台会显示你的 IP
地址。现在你可以像使用原生 Axios
那样发起 HTTP
请求,而无需每次手动导入,因为该模块已将其全局注入。这非常便利,不是吗?接下来我们将从基础模块开始,指导你编写自己的模块。
编写基础模块
正如前文所述,模块本质上是函数,并可选择性地打包为 npm
模块。以下是创建模块所需的最基础结构:
// modules/basic.js
export default function (moduleOptions) {
// ....
}
只需在项目根目录创建 /modules/
文件夹即可开始编写模块代码。若需将模块发布为 npm
包,必须包含以下代码:
module.exports.meta = require('./package.json')
如需创建并发布模块为 npm
包,可参考 Nuxt
社区提供的模板: https://github.com/nuxt-community/module-template/tree/master/template
无论为 Nuxt
社区还是自有项目开发模块,每个模块均可访问以下内容:
-
模块选项
可通过配置文件以
JavaScript
对象形式传递选项:// nuxt.config.js export default { modules: [ ['~/modules/basic/module', { language: 'ES' }], ] }
在模块函数的首个参数
moduleOptions
中访问这些选项:// modules/basic/module.js export default function (moduleOptions) { console.log(moduleOptions) }
控制台将输出:
{ language: 'ES' }
-
配置选项
还可创建自定义选项(如
token
、proxy
或basic
)并传递特定配置(这些选项可用于模块间共享):// nuxt.config.js export default { modules: [ ['~/modules/basic/module'], ], basic: { // 自定义选项 option1: false, option2: true, } }
通过
this.options
访问自定义选项:// modules/basic/module.js export default function (moduleOptions) { console.log(this.options['basic']) }
控制台将输出:
{ option1: false, option2: true }
亦可合并
moduleOptions
与this.options
:// modules/basic/module.js export default function (moduleOptions) { const options = { ...this.options['basic'], ...moduleOptions } console.log(options) }
输出结果为:
{ option1: false, option2: true }
-
Nuxt
实例通过
this.nuxt
访问Nuxt
实例,可用方法参见: https://nuxtjs.org/api/internals-nuxt (例如hook
方法,用于在Nuxt
启动时绑定特定事件的任务) -
ModuleContainer
实例通过
this
访问ModuleContainer
实例,可用方法参见: https://nuxtjs.org/api/internals-module-container (例如常用方法addPlugin
,用于在模块中注册插件) -
module.exports.meta
代码行
如之前所述,若要将模块发布为 npm
包则必须包含这行代码。但在本书中,我们将指导你完成为项目创建模块的步骤。现在让我们通过以下步骤创建一个非常基础的模块:
-
创建包含以下代码的模块文件:
// modules/basic/module.js const { resolve } = require('path') export default function (moduleOptions) { const options = { ...this.options['basic'], ...moduleOptions } // 添加插件 this.addPlugin({ src: resolve(__dirname, 'plugin.js'), fileName: 'basic.js', options }) }
-
创建包含以下代码的
plugin
文件:// modules/basic/plugin.js var options = [] <% if (options.option1 === true) { %> options.push('option 1') <% } %> <% if (options.option2 === true) { %> options.push('option 2') <% } %> <% if (options.language === 'ES') { %> options.push('language ES') <% } %> const basic = function () { return options } export default ({ app }, inject) => { inject('basic', basic) }
请注意,
<%= %>
符号是Lodash
在template
函数中用于插值数据属性的分隔符。我们将在本章后续再次讨论这些符号。如需了解更多关于 Lodash 模板函数的信息,请访问 https://lodash.com/docs/4.17.15#template。 -
在
Nuxt
配置文件中仅包含模块文件路径(/modules/basic/module.js
),并按如下方式提供basic
自定义选项的配置:// nuxt.config.js export default { modules: [ ['~/modules/basic/module', { language: 'ES' }], ], basic: { option1: false, option2: true, } }
-
可以在任意位置使用该模块,例如:
// pages/index.vue mounted () { const basic = this.$basic() console.log(basic) }
-
每次访问首页时,浏览器控制台将显示以下输出:
["option 2", "language ES"]
注意 module.js
如何处理语言和选项等高级配置细节。它还负责注册实际执行工作的 plugin.js
文件。可以看出,模块本质上是插件的封装器。我们将在后续章节深入探讨这一点。
请注意,如果编写的模块仅用于构建时和开发环境,应在 |