西安電話面試:談談Vue數據雙向綁定原理,看看你的回答能打幾分

最近我參加了一次來自西安的電話面試(第二輪,技術面),是大廠仍是小做坊我在這裏按下不表,先來講說此次電面給我留下印象較深的幾道面試題,此次先來談談Vue的數據雙向綁定原理。前端

情景再現:

當我手機鈴聲響起,看着屏幕上面顯示的歸屬地是來自陝西西安的電話,我知道屬於我人生的第一次電話面試要來了。接起電話後,電腦那頭傳來了面試官的聲音(中間省略了一些客套,直接上面試題。)面試官發問,「談談你對Vue數據雙向綁定的認識」。

面試官的這個問題也能夠理解成爲「你是怎麼理解Vue數據綁定,知道它背後實現的原理麼」。通常剛畢業的前端新人可能會說,用v-model。(固然,這多是句廢話)vue

若是簡單說下v-model指令,是Vue的語法糖之類的,可能不會讓面試官滿意,也看不出你對Vue的熟練程度。只能說明你看過Vue的官方文檔,以下圖所示:面試

圖片描述

若是你的回答點到此爲止,基本上是不合格的。此時面試官可能會含蓄地追問:而後呢?npm

其實,若是面試官就這個問題追問,你應該要往兩方面想。往淺了說,若是不用v-model指令,你能用本身的思路實現雙向綁定嗎?往深了挖,他是想問v-model實現背後的原理。數組

若是你能get到這一點,說明你已經上道了,起碼是在公司中開發過業務代碼的小碼農。瀏覽器

那如何在組件中自定義實現相似v-model的數據綁定呢?dom

我先擼爲敬:this

import Vue from 'vue'

const component = {
    template: `
        <div>
            <input type="text" @input="handleInput">
        </div>
    `,
    methods: {
        handleInput (e) {
            this.$emit('input', e.target.value)
        }
    }
}

new Vue({
    conponents: {
        CompA: component
    },
    el: '#root',
    template: `
        <div>
            <comp-a></comp-a>
        </div>
    `
})

這是一個初始化的demo,定義了一個組件component,實例化了一個Vue對象。v-model綁定的值,是從外層的Vue實例中傳進去的。首先咱們要在組件component裏面定義一個props:spa

props: ['value']

而後就能夠在Vue實例的template模板裏面去加上這個value,同時綁定input事件:雙向綁定

template: `
    <div>
        <comp-a :value="value" @input="value = arguments[0]"></comp-a>
    </div>
`,
data () {
    return {
        value: 'runtu'
    }
}

解釋一下,上面代碼中的arguments就是組件template裏面的$emit傳出來的值,全部的參數都會放到arguments裏面,相似於數組。因此這邊咱們把arguments[0]賦值給了value。

一樣,組件component裏面的input也得綁定value:

const component = {
    props: ['value'],
    template: `
        <div>
            <input type="text" @input="handleInput" :value="value">
        </div>
    `,
    methods: {
        handleInput (e) {
            this.$emit('input', e.target.value)
        }
    }
}

等執行完以上步驟,江湖規矩,先在terminal裏面跑一下 npm run dev :

圖片描述

看到demo運行成功地跑在本地8080端口以後,再將視線轉移到瀏覽器裏看一下:

圖片描述

你能夠看到Root裏面的value是「runtu」,當咱們在input框裏輸入什麼,它的data裏面的值就會變成什麼。至關於咱們在Vue實例模板中使用v-model,就等價於咱們去綁定了:value和 @input。

到此,這個demo已經實現了v-model的功能。

固然,此時的template裏面能夠直接將:value和 @input替換爲v-model,效果是同樣的:

template: `
    <div>
        <comp-a v-model="value"></comp-a>
    </div>
`,

這應該是最簡單的實現v-model數據綁定的demo。只須要在一個組件裏面有個props,加上一個value,而後當組件要去修改數據的時候, $emit一個input事件,而且把新的值傳出去。這就實現了Vue裏面的數據雙向綁定。

其實,v-model指令就是在組件上加了一個props,以及增長了一個事件監聽(好比本demo中的input事件),說白了,在v-model裏面做者幫咱們封裝了這個雙向綁定的邏輯,咱們只管拿去用就好。

固然這個demo還能夠更進一步,給變量的名稱定義一下,這樣看起來更加靈活:

const conmponent = {
    model: {
        prop: 'value',
        event: 'change'
    },
    props: ['value'],
    template: `
        <div>
            <input type="text" @input="handleInput" :value="value">
        </div>
    `,
    methods: {
        handleInput (e) {
            this.$emit('change', e.target.value)
        }
    }
}

總結

一句話總結就是:在數據渲染時使用prop渲染數據,將prop綁定到子組件自身的數據上,修改數據時更新自身數據來替代prop,watch子組件自身數據的改變,觸發事件通知父組件更改綁定到prop的數據。

面試官可能還會不厭其煩地問你,Vue數據綁定這樣作的好處是什麼?

敲黑板劃重點:父組件數據改變時,不會修改存儲prop的子組件數據,只是以子組件數據爲媒介,完成對prop的雙向修改。

若是還要繼續深挖,就得搬個小板凳泡上一壺茶準備好瓜子花生,坐下來跟面試官好好聊一聊Vue的響應式原理了,Object.defineProperty 經過 getter 和 setter 劫持了對象賦值的過程,在這個過程當中能夠進行更新 dom 操做等等。

當你能聊到這部分的時候,說明你對Vue的研究達到了必定的程度,面試官也能經過這個問題了解到電話那頭的你對Vue.js知識掌握的深淺,不止停留在使用API作業務開發層面。

固然,這道面試題僅僅是我這次西安電話面試的開胃菜,接下來還有更多面試題等着我去回答,此電面系列文章會第一時間更新在個人公衆號<閏土大叔>裏面,歡迎你們關注。

圖片描述

另外,跟你們透個底,目前爲止,經過幾輪的面試,我已經成功地拿到了這家上市公司的offer。

未完待續......

相關文章
相關標籤/搜索