vue引入js
在Vue.js應用中,可能需要引入Lodash,Moment,Axios,Async等非常好用的JavaScript庫。當專案變得複雜龐大,通常會將程式碼進行模組化拆分。可能還需要跑在不同的環境下,比如瀏覽器,服務端。
如何在各個模組和元件檔案中引入需要的庫呢? 找到一種簡單靠譜的方式,可以省去很多的麻煩。
錯誤示範
全域性變數法
最不靠譜的方式就是將匯入的庫掛在全部變數window 物件下:
entry.js
window._ = require(‘lodash’);MyComponent.vue
export default { created() { console.log(_.isEmpty() ? ‘Lodash
everywhere!’ : ‘Uh oh..’); } }
這種方式的缺點有很多,我們只說其中一個關鍵的點:不支援服務端渲染。當應用跑在服務端時,window物件不存在,當然試圖去訪問window下的屬性會丟擲錯誤。
處處引入法
另外一個不太優雅的方式就是在需要的每個檔案中都引入對應的庫:
MyComponent.vue
import _ from ‘lodash’;
export default { created() { console.log(_.isEmpty() ? ‘Lodash is
available here!’ : ‘Uh oh..’); } }
雖然這方法是可行的,但是太不簡潔。你必須在每個檔案中都記得引入, 而且如果不需要了,又得重新刪除。另外,如果打包策略不夠明智的話,可能會打包出多份重複的程式碼。
正確引入方式
最簡單靠譜的方式是用庫變成Vue的原型物件的屬性。下面,我來演示如何將Moment 庫引入:
entry.js
import moment from ‘moment’; Object.definePrototype(Vue.prototype,
‘$moment’, { value: moment });
由於所有的元件都會繼承Vue原型物件上的方法,因此這些方法在任何元件檔案中都能通過this.$moment 訪問到:
MyNewComponent.vue
export default { created() { console.log(‘The time is ’ .
this.$moment().format(“HH:mm”)); } }
我們來仔細看一下其中的原理。
Object.defineProperty
通常我們會如下設定物件屬性:
Vue.prototype.$moment = moment;
你也可以這麼做,但是Object.defineProperty允許我們用屬性描述器來定義我們的屬性。我們可以定義該屬性是否可寫,可列舉,可配置。
一般情況下,我們不需要用那麼複雜的方式來賦值屬性。但這裡用它有個好處:用屬性描述器定義的屬性是預設只讀的。
這能防止那些腦子不清醒的開發者(很可能是你哦~~)犯下一些低階錯誤:
引用塊內容
this. http.get('/'); // TypeError: this.$http.get is not a function
Object.defineProperty能保護引入的庫不被重新賦值,如果你嘗試重寫,程式會丟擲“TypeError: Cannot assign to read only property”的錯誤。
$
可能你注意到,我們用“ refs, mount。
這種做法不是強制的,這個字首就是為了提醒某些昏昏沉沉的開發者(怎麼又是你?!),這些屬性是公有的,你可以在任何地方使用。反之,某些屬性只能在Vue內部使用。
作為一門以原型為基本的語言,JavaScript中並沒有真正的類,所以也就沒有所謂的公有,私有變數,或者靜態方法。上面這種約定,我覺得是種不錯的選擇。
this
現在你能用this.$libraryName的方式來訪問你需要的庫了。但,你得保證this的指向。如果你在回撥函式中使用this,通常這個this不再指向Vue 例項。
箭頭函式是解決這個問題的好方法。
this. http.get(‘/’) // etc // Only works in a fat arrow callback.
} });
寫成外掛
如果你在專案的很多地方都用了某個庫,或者你希望全域性可用,你可以構建自己的Vue 外掛。
外掛能化繁為簡,能讓你像下面這樣很簡單地引入自己想要的庫:
import MyLibraryPlugin from ‘my-library-plugin’;
Vue.use(MyLibraryPlugin);
就像Vue Route,Vuex等外掛一樣,我們的庫僅僅需要兩行,就能在任何地方使用了。
如何寫外掛
首先,建立一個檔案。本例中,我將引入一個Axios庫的外掛。我們就把這個檔案命名為axios.js 吧。
最關鍵的地方在於,我們需要暴露一個將Vue構造器作為第一個引數的install 方法。
axios.js
export default { install: function(Vue) { // Do stuff } }
然後我們可以用之前的方式將庫新增到Vue的原型物件上:
axios.js
import axios from ‘axios’;
export default { install: function(Vue) {
Object.defineProperty(Vue.prototype, ‘$http’, { value: axios }); } }
接著我們只需要Vue例項的use方法就能將這個庫引入整個專案了。我們像下面程式碼一樣簡單引入:
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外掛的方法名也是這個。然後,讓我們利用第二個引數來修改它。
axios.js
import axios from ‘axios’;
export default { install: function(Vue, name = ‘$http’) {
Object.defineProperty(Vue.prototype, name, { value: axios }); } }entry.js
import AxiosPlugin from ‘./axios.js’; Vue.use(AxiosPlugin, ‘$axios’);
new Vue({ created() { console.log(this.$axios ? ‘Axios works!’ :
‘Uh oh..’); } })
當然上面,我們可以直接在Object.defineProperty的中將name屬性寫死成$axios。也可以在install方法中引入多個需要的庫。