Vue經典面試題: Vue.use和Vue.prototype.$xx有血緣關係嗎?

有關係嗎?

不要緊, 面試的時候總會問如何在Vue的實例上掛載一個方法/屬性, 也就是Vue.prototype的小技巧, 可是忽然有人問他倆有啥關係還真是新鮮. javascript

我想應該是網上有文章寫 Vue.prototype.$xx是用法的, 可是沒有說明Vue.use的用法以及 Vue.prototype.$xx爲何就能在組件內 this.$xx 這麼調用, 因此下面我就細細的說下.

說能學會啥?

看完本文, 能掌握如何定義一個Vue插件, 以及Vue.prototype.$xx的原理.html

Vue.use

用餓了麼UI舉例

下面是餓了麼UI的引入代碼, 你們對這段應該很熟悉了.前端

import Vue from 'vue'
import Element from 'element-ui'
Vue.use(Element)
複製代碼

接下來, 咱們在看下這個Element是什麼vue

這裏咱們看到 Element是個對象, 上面有 version等字段, 其中還有一個 install,他是本文的主角, Vue.use就是要運行這個 install對應的函數.

最小結構

寫一段最少的代碼演示如何用Vue.use初始化插件:java

// 插件
const plugin = {
  install(){
    document.write('我是install內的代碼')
  }
}

// 初始化插件
Vue.use(plugin); // 頁面顯示"我是install內的代碼"
複製代碼

在codepen上看預覽 若是想知道插件的具體實現, 請看 cn.vuejs.org/v2/guide/pl…git

總結

  1. Vue的插件是一個對象, 就像Element.
  2. 插件對象必須有install字段.
  3. install字段是一個函數.
  4. 初始化插件對象須要經過Vue.use().

擴展學習

  1. Vue.use()調用必須在new Vue以前.
  2. 同一個插件屢次使用Vue.use()也只會被運行一次.

Vue.prototype.$xx

好了, 回過頭咱們再看眼上面的圖片, 是否是發現了熟悉的代碼:github

Vue.prototype.$loading = Loading.service;
Vue.prototype.$msgbox = MessageBox;
Vue.prototype.$alert = MessageBox.alert;
...
複製代碼

Vue.prototype 的用法我相信你們都會用, 我作過調查, 我就不囉嗦了, 可是我發現你們好像不知道"因此然".面試

因此然

爲何初始化的時候運行了Vue.prototype.$alert, 而後就能夠在任意組件內部運行this.$alert()了呢? 首先要了解構造函數, 實例, 原型(prototype)這3個概念.element-ui

構造函數, 實例, 原型(prototype)

這3個概念有點老生常談了, 百度一搜不少解釋, 我先舉個例子來和Vue類比你就明白他倆了.微信

首先我寫個假的Vue咱們叫他AVue, 恩, 他是個"贗品", "A貨", 接下來跟我一步一步走:

1. AVue是個構造函數

這裏咱們只模擬下methods功能.

function AVue({methods}){
	for(let key in methods){
		this[key] = methods[key];
	}
}
複製代碼

2. 給AVue的原型上放個$alert

AVue.prototype.$alert = ()=>{document.write('我是個贗品!')}
複製代碼

3. 實例化AVue

實例化Vue的時候咱們知道, 咱們會傳入一個對象, 對象裏面有data/methods等, 個人AVue同樣, 下面咱們讓AVue也學Vue那樣實例化:

// 我只山寨了methods, 因此只能學methods嘍
const av = new AVue({
    methods: {
        say(){
            this.$alert(); 
        }
    }
});

// 調用一下say
av.say(); // 我是個贗品!
複製代碼

在codepen上預覽

總結

好了, 運行到這裏, 我想你應該看明白了吧, 以前你們寫的Vue.prototype.$xx其實只不過是js中函數原型的特性罷了: 函數原型上的屬性/方法, 在函數實例化後, 能夠在任意實例上讀取, 要不你也作個"贗品"試下.

擴展

vue讓你們知道了defineProperty, 咱們本身也能夠用下他, 好比讓Vue.prototype變成不可寫的, 防止被覆蓋.

Object.defineProperty(Vue.prototype, '$alert', {
    writable: false,
    value(){
        console.log('我是行貨!')
    }
});
複製代碼

課後練習

建議你們能夠隨便寫一個vue的插件練手, 好比個人練手項目就是他:

:lollipop:命令式調用vue組件 github.com/any86/vue-c…

微信羣

感謝你們的閱讀, 若有疑問能夠加羣🚀, 羣裏有好多有趣的前端的小夥伴, 讓咱們共同窗習成長吧!

也可加我微信, 我拉你進入微信羣(因爲騰訊對微信羣的100人限制, 超過100人後必須由我拉進去)

相關文章
相關標籤/搜索