在 Vue.js 中使用任意 JavaScript 第三方庫

如何在 Vue.js 項目中 引入 JavaScript 第三方庫vue


全局變量ios


將 JavaScript 第三方庫 添加到項目中,最簡單的辦法是經過將其附加到 window 對象上,以使其成爲全局變量:axios

// entry.js 文件
window._ = require('lodash'); 
JavaScript 代碼:
// MyComponent.vue 文件
export default {
  created() {
    console.log(_.isEmpty() ? 'Lodash everywhere!' : 'Uh oh..');
  }
}

這種狀況會使 window 變量不斷增加,可是最關鍵的是,他們不能使用服務器渲染。當應用程序在服務端運行時,window 對象是 undefined 的,所以嘗試訪問 window 下的屬性將會拋出一個錯誤。服務器


在每一個文件中導入dom


另外一種二流的方法是將庫導入到每一個文件函數

// MyComponent.vue 文件
import _ from 'lodash';
export default {
  created() {
    console.log(_.isEmpty() ? 'Lodash is available here!' : 'Uh oh..');
  }
}

這是有效的,可是你須要重複手動導入和移除,這是一個痛點:你必須記住將這個庫導入到每一個文件中,而後當你的某個文件不用這個庫的時候, 記得要將它從這個文件中移除。若是你沒有正確地設置你的構建工具,則可能會最終致使在構建包中存在同一個庫的多個副本。工具


一個更好的方式ui


在Vue項目中使用Javascript庫的最乾淨,最健壯的方法是將其代理爲 Vue 原型對象的屬性。咱們用這種方式,將 Moment日期和時間庫添加到咱們的項目中:this

JavaScript 代碼:
// entry.js 文件
import moment from 'moment';
Object.definePrototype(Vue.prototype, '$moment', { value: moment });
因爲全部組件都會繼承 Vue 原型對象上方法,這將使 Moment 自動可用於任何組件,沒有全局變量或任何須要手動導入的組件。它能夠在任何 實例/組件 中簡單地經過 this.$moment 訪問被訪問:

JavaScript 代碼:
// MyComponent.vue 文件
export default {
  created() {
    console.log('The time is ' . this.$moment().format("HH:mm"));
  }
}

如今讓咱們花點時間瞭解一下這是如何工做的。prototype

Object.defineProperty
咱們一般會像這樣設置一個對象屬性:

JavaScript 代碼:
Vue.prototype.$moment = moment;

你能夠這麼作,可是經過使用 Object.defineProperty ,咱們可使用 描述符 來定義咱們的屬性。描述符容許咱們設置一些低級細節,例如咱們的屬性是否可寫,以及在 for 循環中枚舉期間是否顯示。

咱們一般不會在平常使用 Javascript 中使用到描述符,由於 99% 的時間咱們不須要這麼細緻的屬性分配。但這裏給咱們一個明顯的優點:默認狀況下,使用描述符建立的屬性是隻讀的。

這意味着,一些糊塗的開發人員(多是你)不能在組件內去作一些很愚蠢的事情, 而且破壞一切.

JavaScript 代碼:
this.$http = 'Assign some random thing to the instance method';
this.$http.get('/'); // TypeError: this.$http.get is not a function
相反, 咱們的只讀實例則能很好的保護咱們的庫, 由於若是有人試圖去覆蓋它, 將會得到一個錯誤:  TypeError: Cannot assign to read only property.

$


您會注意到,咱們將庫代理爲以美圓符號「$」爲前綴的屬性名。 你可能還看過其餘的屬性和方法,例如,$refs, $on, $mount等等也都是以」$」開頭。

雖然屬性名上添加前綴不是必須的,可是這樣作能夠提醒糊塗的開發人員(多是你),這是一個公共API屬性或方法,歡迎你使用,不像其餘屬性的實例,可能只是爲了 Vue 的內部使用。

做爲基於原型的語言,Javascript 中沒有(真正的)類,所以也沒有 「私有」 和 「公共」 變量或 「靜態」 方法。 這個慣例是一種很好的替代品,咱們認爲是值得遵照的約定。


this


你還會注意到,你可使用 this.libraryName 來使用這個庫 ,可是這樣作會有個小小的問題,由於它如今是一個實例方法。

然而,這樣作的結果是,與全局變量不一樣,您在使用庫時必須確保處於正確的做用域中。內部的回調方法不能經過 this 來訪問你的庫。

幸虧,ES6中的箭頭函數是一個不錯的解決方案, 它能確保你在正確的做用域中:

JavaScript 代碼:
// script.js
this.$http.get('/').then(res => {
  if (res.status !== 200) {
    this.$http.get('/') // etc
    // 只在箭頭回調函數中起做用。愚人碼頭注:你也可使用ES5 的 bind();
  }
});

爲何不使它成爲一個插件?

若是您打算在多個 Vue 項目中使用 JavaScript 第三方庫,或者您想與世界分享你的庫,您能夠將其構建成插件!

插件提取複雜性的部分,容許你在項目中簡單地執行如下操做來添加你選擇的庫:

JavaScript 代碼:
// script.js
import MyLibraryPlugin from 'my-library-plugin';
Vue.use(MyLibraryPlugin);

使用這兩行,咱們能夠在任何組件中使用 JavaScript 第三方庫,就像咱們可使用 Vue Router ,Vuex 和其餘使用 Vue.use 的插件同樣。

編寫一個插件
首先,爲您的插件建立一個文件。在這個例子中,我將建立一個插件,將 Axios 添加到你全部的 Vue 實例和組件中,所以我將調用文件 axios.js。

要了解的主要內容是:插件必須公開一個 install 方法,而且將 Vue 構造函數做爲第一個參數:

JavaScript 代碼:
// axios.js
export default {
  install: function(Vue) {
    // Do stuff
  }
}

如今咱們可使用以前介紹的方法將庫添加到原型對象中:

JavaScript 代碼:
// axios.js
import axios from 'axios';
export default {
  install: function(Vue,) {
    Object.defineProperty(Vue.prototype, '$http', { value: axios });
  }
}

咱們如今須要作的事情是 use 實例方法將咱們的庫添加到一個項目。例如,咱們如今能夠輕鬆地添加 Axios 庫:

JavaScript 代碼:
// entry.js
import AxiosPlugin from './axios.js';
Vue.use(AxiosPlugin);
new Vue({
  created() {
    console.log(this.$http ? 'Axios works!' : 'Uh oh..');
  }
})

彩蛋: 插件可選參數


你插件裏的 install 方法容許接受可選參數。 一些開發人員可能不是很喜歡使用 axios 實例的方法名 $http ,由於 Vue Resource 已經使用了這個名字,因此讓咱們使用一個可選參數來讓它們變成你所喜歡的方法名:

JavaScript 代碼:
// axios.js
import axios from 'axios';
export default {
  install: function(Vue, name = '$http') {
    Object.defineProperty(Vue.prototype, name, { value: axios });
  }
}
JavaScript 代碼:
// entry.js
import AxiosPlugin from './axios.js';
Vue.use(AxiosPlugin, '$axios');
new Vue({
  created() {
    console.log(this.$axios ? 'Axios works!' : 'Uh oh..');
  }
})
相關文章
相關標籤/搜索