西安电话面试:谈谈Vue数据双向绑定原理,看看你的回答能打几分

最近我参加了一次来自西安的电话面试(第二轮,技术面),是大厂仍是小做坊我在这里按下不表,先来讲说此次电面给我留下印象较深的几道面试题,此次先来谈谈Vue的数据双向绑定原理。前端

情景再现:vue

当我手机铃声响起,看着屏幕上面显示的归属地是来自陕西西安的电话,我知道属于我人生的第一次电话面试要来了。接起电话后,电脑那头传来了面试官的声音(中间省略了一些客套,直接上面试题。)面试官发问,“谈谈你对Vue数据双向绑定的认识”。面试

面试官的这个问题也能够理解成为“你是怎么理解Vue数据绑定,知道它背后实现的原理么”。通常刚毕业的前端新人可能会说,用v-model。(固然,这多是句废话)npm

若是简单说下v-model指令,是Vue的语法糖之类的,可能不会让面试官满意,也看不出你对Vue的熟练程度。只能说明你看过Vue的官方文档,以下图所示:数组

若是你的回答点到此为止,基本上是不合格的。此时面试官可能会含蓄地追问:而后呢?浏览器

其实,若是面试官就这个问题追问,你应该要往两方面想。往浅了说,若是不用v-model指令,你能用本身的思路实现双向绑定吗?往深了挖,他是想问v-model实现背后的原理。bash

若是你能get到这一点,说明你已经上道了,起码是在公司中开发过业务代码的小码农。dom

那如何在组件中自定义实现相似v-model的数据绑定呢?ui

我先撸为敬: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:

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。

未完待续......

相关文章
相关标签/搜索