我的第一個 Vue 插件

隨着 VueJS 越來越流行,社區創建的 VueJS 插件也變得越來越普遍和強大。

有些插件的確非常有用。例如,令人驚豔的 UI 庫和實用程序插件可以幫助我們節省大量的開發時間。

雖然自己創建插件看似是任務艱鉅,但實際上可行性比你想象的要大得多。

本教程將介紹如何創建你的第一個 VueJS 插件。

一起來試試看吧!!

如何設置插件

從廣義上講,插件就是一個公開.install方法的 JavaScript 模塊。方法需要 2 個參數:

在 Vue 項目中,讓我們在src/plugins創建一個新文件夾。

然後在這個新文件夾中,來創建插件文件。在本教程中,我將其命名爲first-plugin.js

在新插件文件中,我們應該遵循典型的 ES6 模塊化模式,也就是整個export default。Export Default 允許我們從文件中導出插件並允許其他文件的導入。

接下來,插件還需要公開.install(Vue, options)方法。這就是 Vue 在我們安裝插件時實際調用的內容。

所以現在,骨架代碼應該看起來像這樣。

export default {
  // called by Vue.use(FirstPlugin)
  install(Vue, options) {},
};

向插件添加功能

由於我們已經設置了插件的結構,現在讓我們開始構建吧。我們可以使用若干不同的選項來添加功能。這裏介紹一個快速簡單的方法(稍後再介紹更高級的技術)。

構建第一個插件

查看插件運行的一種簡單方法是創建一個全局mixin,包含在所有 Vue 實例中。這可以使用Vue.mixin函數實現。

本質上,VueJS mixins 允許注入額外的組件選項,是在組件之間提取和重用通用功能的好方法。此外,Mixins 還允許插件訪問 Vue 生命週期鉤子。

要將 mixin 添加到插件中,可以在Vue.mixin函數中聲明額外的組件選項。爲此,我添加了一個帶有console.log語句的生命週期鉤子。

此時,插件代碼應該如下所示:

export default {
  // called by Vue.use(FirstPlugin)
  install(Vue, options) {
    // create a mixin
    Vue.mixin({
      created() {
        console.log(Vue);
      },
    });
  },
};

安裝插件

如果你現在運行項目,你會發現什麼都沒有改變。那是因爲還沒有安裝插件。

值得慶幸的是,安裝過程只要兩行就可以,超級簡單。我們只需要在src/main.js文件中導入並安裝插件文件即可。

可以通過以下代碼行完成:

import FirstPlugin from "./plugins/first-plugin.js";

Vue.use(FirstPlugin);

Vue.use的一大優點是確保插件只安裝一次。如果你不知何故不小心添加了兩次,則會減慢 app 的速度,並且可能會弄亂某些功能。幸運的是,Vue 開發人員提供了這個安全保障。

在插件安裝完畢之後,如果現在我們運行項目並查看日誌,那麼可以在控制檯中看到一些輸出。

真正讓這個插件發揮作用

太好了!你已經正式創建了第一個插件。然而這個插件並沒有做什麼太有用的事情。

那麼,試試一些巧妙的方法來讓插件發揮作用吧。

聲明全局屬性

全局數據 / 方法是一種向代碼添加廣泛功能的有用方法。並且非常容易做到。假設我們希望 app 的當前版本號是全局屬性。

代碼如下:

export default {
  install(Vue, options) {
    // define a global property
    Vue.VERSION = "v2.0.3";
  },
};

需要注意的是應避免過度使用全局變量。

定義實例屬性

這是我最喜歡的添加方式之一。實例屬性是一種向 Vue 項目添加數據和方法的便捷方式。我更喜歡使用實例屬性,因爲這樣更能保持全局範圍乾淨且易於理解。

在本文的例子中,我創建了一個實例方法,用於接受一個字符串並放置在<i>標籤內。

注意:$不是必需的語法;這只是 Vue 用於實例屬性以避免衝突的命名約定。

// define an instance method
Vue.prototype.$italicHTML = function (text) {
  return "<i>" + text + "</i>";
};

然後,我們可以在任何實例中使用,就像這樣:

<div v-html="$italicHTML(content)"></div>

構建全局過濾器

VueJS 過濾器是我最喜歡的技術之一,因爲這個技術使得文本轉換非常簡單。而我們所要做的就是調用 Vue 構造函數方法Vue.filterboom

假設我們要使用過濾器從較長的文本生成預覽片段。那麼插件中應該有如下代碼:

// define a global filter
Vue.filter("preview"(value) ={
  if (!value) {
    return "";
  }
  return value.substring(0, userOptions.cutoff) + "...";
});

添加自定義指令

自定義指令是對特定元素進行底層 DOM 訪問的好方法。

讓我們在插件中創建一個自定義指令,自動聚焦到頁面上的元素。

install方法中,我們使用Vue.directive方法來聲明新指令。

// add a custom directive
Vue.directive("focus"{
  // When the bound element is inserted into the DOM...
  inserted: function (el) {
    // Focus the element
    el.focus();
  },
});

然後,添加到元素上。這樣我們就實現瞭如何在頁面加載時自動聚焦文本輸入。

<input type='text' placeholder='Type...' v-focus />

合併選項對象

到目前爲止,我們還沒有觸及install方法的第二個參數。此方法可以讓插件在不同的場景下更加靈活。

爲了使用選項對象,我們首先必須向插件傳遞一些選項。

處理選項對象時的一種最佳實踐是創建一些默認值。我們可以通過在插件文件中私有定義默認選項對象,然後使用 JavaScript 的 spread 語法將默認選項與參數選項合併來實現這一點。

回顧之前的示例,假設我們要添加一個選項,以便允許我們設置文本預覽的截止點。代碼如下:

const defaultOptions = {
  cutoff: 50,
};

export default {
  // called by Vue.use(FirstPlugin)
  install(Vue, options) {
    // merge default options with arg options
    let userOptions = { ...defaultOptions, ...options };

    // REST OF PLUGIN CODE
  },
};

現在,即使沒有給插件傳遞給選項,它也將運行默認值。

如果我們確實想傳遞選項,也很簡單。在src/main.js文件中,我們要做的就是向Vue.use方法添加第二個參數。這個參數將成爲選項對象。

Vue.use(FirstPlugin, { cutoff: 100 });

因爲我們將參數選項放在 spread 語法的右側,所以它會覆蓋默認值。

最終的 Hodge-Podge 插件

請看我們最終的插件代碼。

const defaultOptions = {
  cutoff: 50,
};

export default {
  // called by Vue.use(FirstPlugin)
  install(Vue, options) {
    // merge default options with arg options
    let userOptions = { ...defaultOptions, ...options };

    // create a mixin
    Vue.mixin({
      created() {
        console.log(Vue);
      },
    });

    // define a global property
    Vue.VERSION = "v2.0.3";

    // define an instance method
    Vue.prototype.$italicHTML = function (text) {
      return "<i>" + text + "</i>";
    };

    // define a global filter
    Vue.filter("preview"(value) ={
      if (!value) {
        return "";
      }
      return value.substring(0, userOptions.cutoff) + "...";
    });

    // add a custom directive
    Vue.directive("focus"{
      // When the bound element is inserted into the DOM...
      inserted: function (el) {
        // Focus the element
        el.focus();
      },
    });
  },
};

是的。這個插件在功能方面尚不成熟。但是,經過這一番學習與實踐,我相信你現在肯定更加熟悉這些構建工具、方法和技術了。

總結

哈哈!你的第一個插件完成了。創建 VueJS 插件其實也沒有那麼難,是吧?!

感謝大家的閱讀。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/FZWi9-fsfXqirh4JOS5pqw