插件目录
plugins 目录包含在根 Vue.js 应用程序实例化之前运行的 JavaScript 插件。
这是添加 Vue 插件和注入函数或常量的地方。每次需要使用 Vue.use() 时,都应在 plugins/ 中创建文件,并在 nuxt.config.js 的 plugins 中添加其路径。
外部包
建议在应用程序中使用外部包/模块(著名的例子是 axios )来向服务端和客户端发送 HTTP 请求。
首先通过 npm 或 Yarn 安装:
yarn add @nuxtjs/axios
npm install @nuxtjs/axios
例如,可以配置 axios 拦截器来响应应用程序中所有 API 调用可能产生的错误。此示例中,当 API 返回 500 状态错误时,将用户重定向到名为 sorry 的自定义错误页面。
export default function ({ $axios, redirect }) {
$axios.onError(error => {
if (error.response.status === 500) {
redirect('/sorry')
}
})
}
最后,将模块和新创建的插件添加到项目配置中:
module.exports = {
modules: ['@nuxtjs/axios'],
plugins: ['~/plugins/axios.js']
}
然后可以在页面组件中直接使用:
<template>
<h1>{{ post.title }}</h1>
</template>
<script>
export default {
async asyncData ({ $axios, params }) {
const post = await $axios.$get(`https://api.nuxtjs.dev/posts/${params.id}`)
return { post }
}
}
</script>
不安装模块直接使用 axios 的另一种方式是在 <script> 标签中直接导入 axios:
<script>
import axios from 'axios'
export default {
async asyncData ({ params }) {
const { data: post } = await axios.get(`https://api.nuxtjs.dev/posts/${params.id}`)
return { post }
}
}
</script>
nuxt.config.js 的 build > transpile 选项中添加该包,以便 webpack loader 能够使用插件。build: {
// 可以在此处扩展 webpack 配置
transpile: ['npm-package-name'],
},
Vue 插件
如果想使用 Vue 插件(如 v-tooltip )在应用程序中显示工具提示,需要在启动应用程序前设置插件。
首先安装:
yarn add v-tooltip
npm install v-tooltip
然后创建文件 plugins/vue-tooltip.js:
import Vue from 'vue'
import VTooltip from 'v-tooltip'
Vue.use(VTooltip)
plugins 属性
然后在 nuxt.config.js 的 plugins 键中添加文件路径。plugins 属性可以轻松地将 Vue.js 插件添加到主应用程序中,plugins 属性中定义的所有路径都会在主应用程序初始化之前导入。
export default {
plugins: ['~/plugins/vue-tooltip.js']
}
ES6 插件
如果插件在 node_modules 中且导出 ES6 模块,可能需要将其添加到 transpile 构建选项中:
module.exports = {
build: {
transpile: ['vue-tooltip']
}
}
有关其他构建选项,请参阅 configuration build 文档。
仅客户端或服务端
某些插件可能只在浏览器中工作,因为不支持 SSR。
为插件命名
如果插件只在客户端或服务端运行,可以将 .client.js 或 .server.js 作为插件文件的扩展名,文件会自动只包含在相应(客户端或服务端)一侧。
export default {
plugins: [
'~/plugins/foo.client.js', // 仅客户端
'~/plugins/bar.server.js', // 仅服务端
'~/plugins/baz.js' // 客户端和服务端
]
}
对象语法
也可以在 plugins 的 mode 属性('client' 或 'server')中使用对象语法:
export default {
plugins: [
{ src: '~/plugins/both-sides.js' },
{ src: '~/plugins/client-only.js', mode: 'client' }, // 仅客户端
{ src: '~/plugins/server-only.js', mode: 'server' } // 仅服务端
]
}
注入 $root 和上下文
有时想在应用程序中使某些函数或值可用,可以将这些变量注入到 Vue 实例(客户端)、上下文(服务端)甚至 Vuex store 中。按照惯例,这些函数前缀为 $。
Nuxt 提供了 inject(key, value) 方法来轻松实现这一点。导出函数时,inject 作为第二个参数给出,$ 会自动添加到键的前面。
export default ({ app }, inject) => {
// 将 $hello(msg) 注入到 Vue、上下文和 store 中
inject('hello', msg => console.log(`Hello ${msg}!`))
}
export default {
plugins: ['~/plugins/hello.js']
}
现在 $hello 服务可以在页面、组件、插件和 store 操作的 context 和 this 中访问:
export default {
mounted() {
this.$hello('mounted')
// 会调用 console.log 'Hello mounted!'
},
asyncData({ app, $hello }) {
$hello('asyncData')
// 如果使用 Nuxt <= 2.12,请用 👇
app.$hello('asyncData')
}
}
export const state = () => ({
someValue: ''
})
export const actions = {
setSomeValueToWhatever({ commit }) {
this.$hello('store action')
const newValue = 'whatever'
commit('changeSomeValue', newValue)
}
}
Vue.use()、Vue.component(),也不要在此函数内全局连接 Vue,专用于 Nuxt 注入,否则会在服务端造成内存泄漏。extendPlugins 属性
可以扩展插件或更改 Nuxt 创建的插件顺序。此函数接受插件 对象数组,并返回插件对象数组。
更改插件顺序的示例:
export default {
extendPlugins(plugins) {
const pluginIndex = plugins.findIndex(
({ src }) => src === '~/plugins/shouldBeFirst.js'
)
const shouldBeFirstPlugin = plugins[pluginIndex]
plugins.splice(pluginIndex, 1)
plugins.unshift(shouldBeFirstPlugin)
return plugins
}
}
全局 mixin
全局 mixin 可以通过 Nuxt 插件轻松添加,但如果处理不当可能会导致问题和内存泄漏。向应用程序添加全局 mixin 时,应始终使用标志以避免多次注册:
import Vue from "vue"
// 确保标志名称唯一
// 以避免与其他 mixin 冲突
if (!Vue.__my_mixin__) {
Vue.__my_mixin__ = true
Vue.mixin({ ... }) // 设置 mixin
}