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

情景再现:

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

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

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

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

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

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

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

我先撸为敬:

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。

未完待续......

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

  1. vue数据双向绑定原理

    vue的数据双向绑定的小例子: .html <!DOCTYPE html> <html> <head> <meta charset=utf-> < ...

  2. Vue数据双向绑定原理及简单实现

    嘿,Goodgirl and GoodBoy,点进来了就看完点个赞再go. Vue这个框架就不简单介绍了,它最大的特性就是数据的双向绑定以及虚拟dom.核心就是用数据来驱动视图层的改变.先看一段代码. ...

  3. Vue数据双向绑定原理(vue2向vue3的过渡)

    众所周知,Vue的两大重要概念: 数据驱动 组件系统 1 2 接下来我们浅析数据双向绑定的原理 一.vue2 1.认识defineProperty vue2中的双向绑定是基于definePropert ...

  4. 【学习笔记】剖析MVVM框架,简单实现Vue数据双向绑定

    前言: 学习前端也有半年多了,个人的学习欲望还比较强烈,很喜欢那种新知识在自己的演练下一点点实现的过程.最近一直在学vue框架,像网上大佬说的,入门容易深究难.不管是跟着开发文档学还是视频教程,按步骤 ...

  5. vue的双向绑定原理及实现

    前言 使用vue也好有一段时间了,虽然对其双向绑定原理也有了解个大概,但也没好好探究下其原理实现,所以这次特意花了几晚时间查阅资料和阅读相关源码,自己也实现一个简单版vue的双向绑定版本,先上个成果图 ...

  6. vue数据双向绑定的原理、虚拟dom的原理

    vue数据双向绑定的原理https://www.cnblogs.com/libin-1/p/6893712.html 虚拟dom的原理https://blog.csdn.net/u010692018/ ...

  7. 对象的属性类型 和 VUE的数据双向绑定原理

    如[[Configurable]] 被两对儿中括号 括起来的表示 不可直接访问他们 修改属性类型:使用Object.defineProperty()  //IE9+  和标准浏览器  支持 查看属性的 ...

  8. vue的双向绑定原理解析(vue项目重构二)

    现在的前端框架 如果没有个数据的双向/单向绑定,都不好意思说是一个新的框架,至于为什么需要这个功能,从jq或者原生js开始做项目的前端工作者,应该是深有体会. 以下也是个人对vue的双向绑定原理的一些 ...

  9. vue的双向绑定原理浅析与简单实现

    很久之前看过vue的一些原理,对其中的双向绑定原理也有一定程度上的了解,只是最近才在项目上使用vue,这才决定好好了解下vue的实现原理,因此这里对vue的双向绑定原理进行浅析,并做一个简单的实现. ...

随机推荐

  1. Mybatis框架入门

    Mybaits框架 一.什么是Mybatis MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了googl ...

  2. TF中conv2d和kernel_initializer方法

    conv2d中的padding 在使用TF搭建CNN的过程中,卷积的操作如下 convolution = tf.nn.conv2d(X, filters, strides=[1,2,2,1], pad ...

  3. api-gateway实践(05)新网关工作 - 缓存定义

    一.缓存分类 1.服务注册信息 1.1.[GroupCode_VersionCode]对应[Version定义]的缓存                       缓存类型:hash         ...

  4. Linux搭建Apache+Tomcat实现负载均衡

    一.首先需要安装java,详见http://www.cnblogs.com/fun0623/p/4350004.html 二.编译安装Apache,详见http://www.cnblogs.com/f ...

  5. 基于session认证 相亲小作业

    基于session认证  相亲小作业 用户登录 如果男用户登录,显示女生列表 如果女用户登录,显示男生列表 urls ===========================urls========== ...

  6. jmc远程连接windows环境tomcat

    新人报道,先发个小贴赚点人气,本人目前还是小菜鸟,想要飞却怎么也飞不高,哈哈,转到正题,最近发现这个JMC挺好用的,而且也不用像Jprofile需要破解,本地连接挺方便的, 但配置服务器确实挺坑的,按 ...

  7. 有些ES6方法极简,但是性能不够好

    So,也许你觉得ES6让你视野大开,但是并不是性能也能跟得上~ 首先,让我们先来一个简单的性能测试: 数组去重 es5写法: function delSame(arr){ var n = []; ; ...

  8. java中lamda表达式的应用

    lamda表达式主要是为了解决匿名内部类的繁琐过程 范例:简单的lamda表达式 此处使用匿名内部类 package com.java.demo; interface IMessage{ public ...

  9. 在Unity3D中利用 RenderTexture 实现游戏内截图

    using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; publ ...

  10. C#中string的相关方法

    下面的方法一般都有很多重载形式,作为初学者的我先把我用过的记录下来吧...以后用到其他的可以一点点添加: 直接上例子吧.先定义两个字符串str1,str2(不要吐槽命名==) string str1, ...