plugins
Nuxt 擁有一個外掛系統,用於在建立 Vue 應用程式時使用 Vue 外掛及其他功能。
Nuxt 會自動讀取 app/plugins/
目錄中的檔案,並在建立 Vue 應用程式時載入它們。
所有外掛都會自動註冊,您無需將它們單獨新增到
nuxt.config
中。您可以在檔名稱中使用
.server
或 .client
字尾,以便僅在伺服器端或客戶端載入外掛。已註冊的外掛
只有目錄頂層的檔案(或任何子目錄中的索引檔案)才會被自動註冊為外掛。
目錄結構
-| plugins/
---| foo.ts // scanned
---| bar/
-----| baz.ts // not scanned
-----| foz.vue // not scanned
-----| index.ts // currently scanned but deprecated
只有 foo.ts
和 bar/index.ts
會被註冊。
要在子目錄中新增外掛,您可以使用 nuxt.config.ts
中的 app/plugins
選項
nuxt.config.ts
export default defineNuxtConfig({
plugins: [
'~/plugins/bar/baz',
'~/plugins/bar/foz',
],
})
建立外掛
傳遞給外掛的唯一引數是 nuxtApp
。
plugins/hello.ts
export default defineNuxtPlugin((nuxtApp) => {
// Doing something with nuxtApp
})
物件語法外掛
也可以使用物件語法定義外掛,以實現更高階的用例。例如
plugins/hello.ts
export default defineNuxtPlugin({
name: 'my-plugin',
enforce: 'pre', // or 'post'
async setup (nuxtApp) {
// this is the equivalent of a normal functional plugin
},
hooks: {
// You can directly register Nuxt app runtime hooks here
'app:created' () {
const nuxtApp = useNuxtApp()
// do something in the hook
},
},
env: {
// Set this value to `false` if you don't want the plugin to run when rendering server-only or island components.
islands: true,
},
})
如果您使用物件語法,屬性將進行靜態分析以生成更最佳化的構建。因此,您不應在執行時定義它們。
例如,設定
例如,設定
enforce: import.meta.server ? 'pre' : 'post'
會破壞 Nuxt 將來為您的外掛所做的任何最佳化。Nuxt 在使用物件語法時會靜態預載入任何鉤子監聽器,讓您無需擔心外掛註冊的順序即可定義鉤子。註冊順序
您可以透過在檔名上新增“字母順序”編號來控制外掛的註冊順序。
目錄結構
plugins/
| - 01.myPlugin.ts
| - 02.myOtherPlugin.ts
在此示例中,02.myOtherPlugin.ts
將能夠訪問 01.myPlugin.ts
注入的任何內容。
這在您有一個外掛依賴於另一個外掛的情況下很有用。
如果您不熟悉“字母順序”編號,請記住檔名是按字串而不是數字值排序的。例如,
10.myPlugin.ts
會排在 2.myOtherPlugin.ts
之前。這就是為什麼示例中個位數數字前面加上 0
的原因。載入策略
並行外掛
預設情況下,Nuxt 按順序載入外掛。您可以將外掛定義為 parallel
,這樣 Nuxt 就不會等到外掛執行結束才載入下一個外掛。
plugins/my-plugin.ts
export default defineNuxtPlugin({
name: 'my-plugin',
parallel: true,
async setup (nuxtApp) {
// the next plugin will be executed immediately
},
})
帶依賴的外掛
如果一個外掛需要在另一個外掛執行之前等待,您可以將該外掛的名稱新增到 dependsOn
陣列中。
plugins/depending-on-my-plugin.ts
export default defineNuxtPlugin({
name: 'depends-on-my-plugin',
dependsOn: ['my-plugin'],
async setup (nuxtApp) {
// this plugin will wait for the end of `my-plugin`'s execution before it runs
},
})
使用組合式函式
app/plugins/hello.ts
export default defineNuxtPlugin((nuxtApp) => {
const foo = useFoo()
})
但是,請記住有一些限制和差異
如果組合式函式依賴於稍後註冊的另一個外掛,它可能無法工作。
外掛按順序且在所有其他內容之前呼叫。您可能正在使用一個依賴於尚未呼叫的另一個外掛的組合式函式。
外掛按順序且在所有其他內容之前呼叫。您可能正在使用一個依賴於尚未呼叫的另一個外掛的組合式函式。
如果組合式函式依賴於 Vue.js 生命週期,它將無法工作。
通常,Vue.js 組合式函式繫結到當前元件例項,而外掛僅繫結到
通常,Vue.js 組合式函式繫結到當前元件例項,而外掛僅繫結到
nuxtApp
例項。提供輔助函式
如果您想在 NuxtApp
例項上提供輔助函式,請在 provide
鍵下從外掛返回它。
export default defineNuxtPlugin(() => {
return {
provide: {
hello: (msg: string) => `Hello ${msg}!`,
},
}
})
export default defineNuxtPlugin({
name: 'hello',
setup () {
return {
provide: {
hello: (msg: string) => `Hello ${msg}!`,
},
}
},
})
然後您可以在元件中使用該輔助函式
app/components/Hello.vue
<script setup lang="ts">
// alternatively, you can also use it here
const { $hello } = useNuxtApp()
</script>
<template>
<div>
{{ $hello('world') }}
</div>
</template>
請注意,我們強烈建議使用
組合式函式
而不是提供輔助函式,以避免汙染全域性名稱空間並保持主捆綁入口檔案小巧。瞭解更多資訊。
型別化外掛
如果您從外掛中返回輔助函式,它們將自動進行型別化;您會發現它們在
useNuxtApp()
的返回值中以及您的模板中都有型別定義。如果您需要在另一個外掛中使用提供的輔助函式,您可以呼叫 useNuxtApp()
來獲取型別化版本。但通常情況下,除非您確定外掛的順序,否則應避免這樣做。對於高階用例,您可以像這樣宣告注入屬性的型別
index.d.ts
declare module '#app' {
interface NuxtApp {
$hello (msg: string): string
}
}
declare module 'vue' {
interface ComponentCustomProperties {
$hello (msg: string): string
}
}
export {}
如果您正在使用 WebStorm,您可能需要增強
@vue/runtime-core
直到此問題得到解決。Vue 外掛
如果您想使用 Vue 外掛,例如vue-gtag來新增 Google Analytics 標籤,您可以使用 Nuxt 外掛來實現。
首先,安裝 Vue 外掛依賴項
npm install --save-dev vue-gtag-next
yarn add --dev vue-gtag-next
pnpm add -D vue-gtag-next
bun add -D vue-gtag-next
然後建立一個外掛檔案
app/plugins/vue-gtag.client.ts
import VueGtag, { trackRouter } from 'vue-gtag-next'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(VueGtag, {
property: {
id: 'GA_MEASUREMENT_ID',
},
})
trackRouter(useRouter())
})
Vue 指令
同樣,您可以在外掛中註冊自定義 Vue 指令。
plugins/my-directive.ts
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.directive('focus', {
mounted (el) {
el.focus()
},
getSSRProps (binding, vnode) {
// you can provide SSR-specific props here
return {}
},
})
})
如果您註冊 Vue 指令,則必須在客戶端和伺服器端都註冊它,除非您只在渲染其中一方時使用它。如果指令僅在客戶端有意義,您始終可以將其移動到
~/plugins/my-directive.client.ts
,並在 ~/plugins/my-directive.server.ts
中為伺服器提供一個“存根”指令。