直接跳到內容
本頁目錄

插件

介紹

插件 (Plugins) 是一種能為 Vue 添加全局功能的工具代碼。下面是如何安裝一個插件的示例:

js
import { createApp } from 'vue'

const app = createApp({})

app.use(myPlugin, {
  /* 可選的選項 */
})

一個插件可以是一個擁有 install() 方法的對象,也可以直接是一個安裝函數本身。安裝函數會接收到安裝它的應用實例和傳遞給 app.use() 的額外選項作為參數:

js
const myPlugin = {
  install(app, options) {
    // 配置此應用
  }
}

插件沒有嚴格定義的使用範圍,但是插件發揮作用的常見場景主要包括以下幾種:

  1. 通過 app.component()app.directive() 註冊一到多個全局組件或自定義指令。

  2. 通過 app.provide() 使一個資源可被注入進整個應用。

  3. app.config.globalProperties 中添加一些全局實例屬性或方法

  4. 一個可能上述三種都包含了的功能庫 (例如 vue-router)。

編寫一個插件

為了更好地理解如何構建 Vue.js 插件,我們可以試著寫一個簡單的 i18n (國際化 (Internationalization) 的縮寫) 插件。

讓我們從設置插件對象開始。建議在一個單獨的文件中創建並導出它,以保證更好地管理邏輯,如下所示:

js
// plugins/i18n.js
export default {
  install: (app, options) => {
    // 在這裡編寫插件代碼
  }
}

我們希望有一個翻譯函數,這個函數接收一個以 . 作為分隔符的 key 字符串,用來在用戶提供的翻譯字典中查找對應語言的文本。期望的使用方式如下:

template
<h1>{{ $translate('greetings.hello') }}</h1>

這個函數應當能夠在任意模板中被全局調用。這一點可以通過在插件中將它添加到 app.config.globalProperties 上來實現:

js
// plugins/i18n.js
export default {
  install: (app, options) => {
    // 注入一個全局可用的 $translate() 方法
    app.config.globalProperties.$translate = (key) => {
      // 獲取 `options` 對象的深層屬性
      // 使用 `key` 作為索引
      return key.split('.').reduce((o, i) => {
        if (o) return o[i]
      }, options)
    }
  }
}

我們的 $translate 函數會接收一個例如 greetings.hello 的字符串,在用戶提供的翻譯字典中查找,並返回翻譯得到的值。

用於查找的翻譯字典對象則應當在插件被安裝時作為 app.use() 的額外參數被傳入:

js
import i18nPlugin from './plugins/i18n'

app.use(i18nPlugin, {
  greetings: {
    hello: 'Bonjour!'
  }
})

這樣,我們一開始的表達式 $translate('greetings.hello') 就會在運行時被替換為 Bonjour! 了。

TypeScript 用戶請參考:擴展全局屬性

TIP

請謹慎使用全局屬性,如果在整個應用中使用不同插件注入的太多全局屬性,很容易讓應用變得難以理解和維護。

插件中的 Provide / Inject

在插件中,我們可以通過 provide 來為插件用戶供給一些內容。舉例來說,我們可以將插件接收到的 options 參數提供給整個應用,讓任何組件都能使用這個翻譯字典對象。

js
// plugins/i18n.js
export default {
  install: (app, options) => {
    app.provide('i18n', options)
  }
}

現在,插件用戶就可以在他們的組件中以 i18n 為 key 注入並訪問插件的選項對象了。

vue
<script setup>
import { inject } from 'vue'

const i18n = inject('i18n')

console.log(i18n.greetings.hello)
</script>
js
export default {
  inject: ['i18n'],
  created() {
    console.log(this.i18n.greetings.hello)
  }
}
插件已經加載完畢