vue.use()方法從源碼到使用


在做 vue 開發的時候大家一定經常接觸 Vue.use() 方法,官網給出的解釋是: 通過全局方法 Vue.use() 使用插件;我覺得把使用理解成注冊更合適一些,首先看下面常見的注冊場景。

1
2
3
4
5
6
7
8
import Router from 'vue-router'
Vue.use(Router)
 
import Vuex from 'vuex'
Vue.use(Vuex)
 
import Echarts from 'echarts'
Vue.prototype.$echarts = Echarts

關於 echarts 的注冊很簡單,直接掛在 Vue 方法的原型上,通過原型鏈繼承的關系可以在任意一個組件里通過 this.$echarts 訪問到 echarts 實例,我們來寫一個簡單的例子證明一下。

1
2
3
4
5
6
7
8
function myVue(title){
  this .title = title
}
myVue.prototype.myUse = '在原型上添加公共屬性'
const A = new myVue( '我是實例A' )
const B = new myVue( '我是實例B' )
console.log(A.title, B.title, A.myVue, B.myVue, )
// 我是實例A 我是實例B 在原型上添加公共屬性 在原型上添加公共屬性

而 Router 和 Vuex 的注冊就要去分析 Vue.use() 的源碼了,在分析源碼之前先總結一下官方對 Vue.use() 方法的說明:

  • 通過全局方法 Vue.use() 使用插件
  • Vue.use 會自動阻止多次注冊相同插件
  • 它需要在你調用 new Vue() 啟動應用之前完成
  • Vue.use() 方法至少傳入一個參數,該參數類型必須是 Object 或 Function,如果是 Object 那么這個 Object 需要定義一個 install 方法,如果是 Function 那么這個函數就被當做 install 方法。在 Vue.use() 執行時 install 會默認執行,當 install 執行時第一個參數就是 Vue,其他參數是 Vue.use() 執行時傳入的其他參數。

官網說 Vue.use() 是用來使用插件的,那么傳入的 Router 和 Vuex 就是這里指的插件,而這個插件本質上又是一個 install 方法。至於 install 方法內部實現了什么邏輯就由插件自身的業務決定了。

vue.use()源碼


下面切入本文的主題。我們知道了vue.use()怎么用還不夠,還要知道它的內部是怎么實現的。下面展示源碼:

import { toArray } from '../util/index' export function initUse (Vue: GlobalAPI) { Vue.use = function (plugin: Function | Object) { const installedPlugins = (this._installedPlugins || (this._installedPlugins = [])) if (installedPlugins.indexOf(plugin) > -1) { return this } // additional parameters const args = toArray(arguments, 1) args.unshift(this) if (typeof plugin.install === 'function') { plugin.install.apply(plugin, args) } else if (typeof plugin === 'function') { plugin.apply(null, args) } installedPlugins.push(plugin) return this } }

vue.use()源碼中采用了flow的語法。flow語法,官方解釋是:

Flow is a static type checker for your JavaScript code. It does a lot of work to make you more productive. Making you code faster, smarter, more confidently, and to a bigger scale.

簡單的意思就是flow是JavaScript代碼的靜態類型檢查工具。官網鏈接
使用flow的好處就是:在編譯期對js代碼變量做類型檢查,縮短調試時間, 減少因類型錯誤引起的bug。我們都知道js是解釋執行語言,運行的時候才檢查變量的類型,flow可以在編譯階段就對js進行類型檢查。

下面將對vue.use()源碼進行解讀:

1、首先先判斷插件plugin是否是對象或者函數:
Vue.use = function (plugin: Function | Object)

2、判斷vue是否已經注冊過這個插件
installedPlugins.indexOf(plugin) > -1
如果已經注冊過,跳出方法

3、取vue.use參數。
const args = toArray(arguments, 1)

4、toArray()取參數
代碼:

export function toArray (list: any, start?: number): Array<any> { start = start || 0 let i = list.length - start const ret: Array<any> = new Array(i) while (i--) { ret[i] = list[i + start] } return ret }

let i = list.length - start意思是vue.use()方法傳入的參數,除第一個參數外(第一個參數是插件plugin),其他參數都存儲到一個數組中,並且將vue對象插入到參數數組的第一位。最后參數數組就是[vue,arg1,arg2,...]

5、判斷插件是否有install方法,如果有就執行install()方法。沒有就直接把plugin當Install執行。

if (typeof plugin.install === 'function') { plugin.install.apply(plugin, args) } else if (typeof plugin === 'function') { plugin.apply(null, args) }

plugin.install.apply(plugin, args)將install方法綁定在plugin環境中執行,並且傳入args參數數組進install方法。此時install方法內的this指向plugin對象。
plugin.apply(null, args) plugin內的this指向null.

最后告知vue該插件已經注冊過installedPlugins.push(plugin)保證每個插件只會注冊一次。

Vue.use()有什么用

在 install 里我們可以拿到 Vue 那么和 Vue 相關的周邊工作都可以考慮放在 Vue.use() 方法里,比如:

  • directive注冊
  • mixin注冊
  • filters注冊
  • components注冊
  • prototype掛載
  • ...

echarts 用 Vue.use() 來注冊

main.js

1
2
3
4
5
6
7
import Vue from 'vue'
import echarts from './echarts.js'
Vue.use(echarts)
 
new Vue({
  ...
})

echarts.js

1
2
3
4
5
6
import Echarts from 'echarts'
export default {
  install(Vue){
   Vue.prototype.$echarts = Echarts
  }
}

這樣寫的好處是可以在 install 的文件里做更多配置相關的工作,main.js 不會變的臃腫,更方便管理。

全局組件用 Vue.use() 來注冊

base.js

1
2
3
4
5
6
7
8
import a from './a'
import b from './b'
let components = { a, b }
const installBase = {
  install (Vue) {
   Object.keys(components).map(key => Vue.component(key, components[key]))
  }
}

main.js

1
2
3
4
5
6
7
import Vue from 'vue'
import base from './base.js'
Vue.use(base)
 
new Vue({
  ...
})


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM