透過 100 多個提示來學習 Nuxt!

外掛

Nuxt 具有外掛系統,可在建立 Vue 應用程式時使用 Vue 外掛程式及其他功能。

Nuxt 會自動讀取 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.tsbar/index.ts 會被註冊。

若要在子目錄中加入外掛,您可以使用 nuxt.config.ts 中的 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
} })
觀看 Alexander Lichter 關於 Nuxt 外掛的物件語法的影片。
如果您使用的是物件語法,則會靜態分析這些屬性,以產生更優化的建置。因此您不應在執行階段定義它們。
例如,設定 enforce: import.meta.server ? 'pre' : 'post' 會破壞 Nuxt 未來可以為您的外掛執行的任何最佳化。當使用物件語法時,Nuxt 會靜態預先載入任何 hook 監聽器,讓您可以定義 hook,而無需擔心外掛註冊的順序。

註冊順序

您可以透過在檔案名稱前加上「字母」編號來控制外掛註冊的順序。

目錄結構
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 } })

使用 Composables

您可以在 Nuxt 外掛中使用 composables 以及 utils

plugins/hello.ts
export default defineNuxtPlugin((nuxtApp) => {
  const foo = useFoo()
})

不過,請記住有一些限制和差異

如果一個 composable 依賴於稍後註冊的另一個外掛,則它可能無法運作。
外掛會依序呼叫,並且早於其他所有內容。您可能會使用一個依賴於尚未被呼叫的另一個外掛的 composable。
如果一個 composable 依賴於 Vue.js 生命週期,則它將無法運作。
通常,Vue.js composables 會繫結到目前的元件實例,而外掛程式只會繫結到 nuxtApp 實例。

提供輔助程式

如果您想要在 NuxtApp 實例上提供輔助程式,請從外掛程式中以 provide 索引鍵傳回它。

export default 
defineNuxtPlugin
(() => {
return {
provide
: {
hello
: (
msg
: string) => `Hello ${
msg
}!`
} } })

然後您可以在您的元件中使用該輔助程式

components/Hello.vue
<script setup lang="ts">
// alternatively, you can also use it here
const { $hello } = useNuxtApp()
</script>

<template>
  <div>
    {{ $hello('world') }}
  </div>
</template>
請注意,我們強烈建議使用 composables,而不是提供輔助函式,以避免污染全域命名空間並保持您的主要套件入口檔案小巧。
如果您的外掛程式提供 refcomputed,它將不會在元件的 <template> 中被解包。
這是由於 Vue 如何處理非頂層的模板 refs。您可以在 Vue 文件中閱讀更多相關資訊。

外掛程式的型別

如果您從外掛程式傳回輔助函式,它們將會自動被加入型別;您會發現它們的型別會用於 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

然後建立一個外掛程式檔案

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 中為伺服器提供一個「虛擬」指令。
請在 Vue 文件中的自訂指令閱讀更多相關資訊。