我又来吹牛逼了,这次我们简单说一下vue的数据双向绑定,我们这次不背题,而是要你理解这个流程,保证读完就懂,逢人能讲,面试必过,如果没做到,请再来看一遍,走起:

  

  介绍双向数据之前,我们先解释几个名词:

  1、什么是setter、getter ?

  答:首先,别误以为他们就是一会要说的get、set,我们先看一句定义:

    对象有两种属性:(1)数据属性,就是我们经常使用的属性(2)访问器属性,也称存取器属性(存取器属性就是一组获取和设置值的函数)

  

  再看一行代码:

  

  log打印出来的如下:

  

  数据属性就是a和b;

  get和set就是关键字 它们后面各自对应一个函数,这个函数就是上面红字部分所讲的,存储器属性。

  get对应的方法称为getter,负责获取值,它不带任何参数。set对应的方法为setter,负责设置值,在它的函数体中,一切的return都是无效的。

  2、什么是Object.defineProperty() ?

  答:老规矩走起,我们先看一句定义:

  对象是由多个名/值对组成的无序的集合。对象中每个属性对应任意类型的值。

  

  定义对象可以使用构造函数或字面量的形式:

  

  

  除了以上添加属性的方式,当然还可以使用Object.defineProperty定义新属性或修改原有的属性;

  语法:

  Object.defineProperty(obj, prop, descriptor)

  参数:

  obj:必需。目标对象;
  prop:必需。需定义或修改的属性的名字;
  descriptor:必需。目标属性所拥有的特性;

  返回值:

  传入函数的对象,即第一个参数obj;

  OK,定义介绍完了,我们现在说一下一会关于双向绑定我们要用到的知识点:存取器描述;(诶?你是不是发现和上面好像有点关系)

  

  对头,它是这样使用的:

  

  现在无论是你获取还是设置我们都可以接到通知,是不是有一点双向数据绑定的影子了,别急下面还有;

  

  OK,我终于叨叨完没用的了,现在开始说正题,如何理解Vue的双向数据绑定,哈哈,先来一个定义:

  Vue是采用数据劫持结合发布/订阅模式的方式,通过Object.defineProperty()来劫持各个属性的settergetter,在数据变动时发布消息给订阅者,触发相应的监听回调。

  我们来看一个很粗暴的栗子,low版双向绑定:

  

  是不是有点明白了呢,当然这也不是全部,我们刚刚说的大概就是下面Observer的部分,对每个vue中的data中定义的属性循环用Object.defineProperty()实现数据劫持,以便利用其中的setter和getter,然后通知订阅者,订阅者会触发它的update方法,对视图进行更新。

  

  别急,下面也很简单:

  Dep,它就像一个依赖管理一样,小伙伴又问啥是依赖管理倪? 上图!

  

  我用一个例子来解释一下上面这张图 下面高能预警:

  在vue中v-model,v-name,{{}}等都可以对数据进行展示,也就是说假如一个属性都通过这三个指令了,那么每当这个属性改变的时候,相应的这个三个指令的html视图也必须改变;

  于是vue中就是每当有这样的可能用到双向绑定的指令,就在一个Dep中增加一个订阅者(addSub),其订阅者只是更新自己的指令对应的数据,也就是v-model='name'和{{name}}有两个对应的订阅者,各自管理自己的地方;

  每当属性的set方法触发,就循环更新Dep中的订阅者(notify);

  OK,Dep是不是很明白了呢

  集合上面的那张图来看,就是Observer一旦有了set触发,就会通知到Dep,那Dep接到通知之后呢?从图上来看,下面所讲的就应该是Compile了,也很简单:

  首先,先要知道它负责干什么?

  compile主要做的事情是解析模板指令,将模板中的变量替换成数据

  其次知道它什么时候要工作,只有两种情况,先上图:

  

  

  1)初始化,init的时候 初始化渲染页面视图;

  2)将每个指令对应的节点绑定更新函数,添加监听数据的订阅者

  Dep负责维护依赖,而订阅者则来自于compile,一旦有数据变动,则会绑定更新函数,此时也就是产生了订阅者,这个时候Dep内就增加了一个订阅者,而一旦数据变动,则会收到通知,更新视图;

  好了,你是不是觉得上面这行说不通,或是读不通,当然,因为上面的这个流程了缺少了,我们最后要说的Watcher,我把上面这句话补全,就是Watcher的工作了;

  Dep负责维护依赖,而订阅者则来自于compile,一旦有数据变动,则会通过Watcher绑定更新函数,此时Watcher也向Dep中添加了订阅者,一旦Dep接到Observer的通知,它就会再去通知WatcherWatcher则会调用自身的update()方法,并触发Compile中绑定的回调,更新视图;

  

  最后敲黑板:

  首先我们为每个vue属性用Object.defineProperty()实现数据劫持,为每个属性分配一个订阅者集合的管理数组dep;

  然后在编译的时候在该属性的数组dep中添加订阅者,v-model会添加一个订阅者,{{}}也会,v-bind也会,只要用到该属性的指令理论上都会;

  接着为input会添加监听事件,修改值就等于为该属性赋值,则会触发该属性的set方法,在set方法内通知订阅者数组dep,订阅者数组循环调用各订阅者的update方法更新视图。

  参考干货:

  https://www.cnblogs.com/zhenfei-jiang/p/7542900.html

  https://segmentfault.com/a/1190000006599500

  感谢巨人的肩膀

  

  

  

  

  

     

    

Vue数据双向绑定(面试必备) 极简版的更多相关文章

  1. Vue生命周期的执行过程(面试必备) 极简版

    最近准备面试,临时抱佛脚的来回顾一下vue相关的面试题,当然这是不对的,平时还是要努力呀,走起: 1.创建vue实例,Vue(); 2.在创建Vue实例的时候,执行了init(),在init过程中首先 ...

  2. Vue Virtual Dom 和 Diff原理(面试必备) 极简版

    我又来了,这是Vue面试三板斧的最后一招,当然也是极其简单了,先说Virtual Dom,来一句概念: 用js来模拟DOM中的节点.传说中的虚拟DOM. 再来一张图: 是不是一下子秒懂  没懂再来一张 ...

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

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

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

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

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

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

  6. vue数据双向绑定原理

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

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

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

  8. vue数据双向绑定

    Vue的双向绑定是通过数据劫持结合发布-订阅者模式实现的,即通过Object.defineProperty监听各个属性的setter,然后通知订阅者属性发生变化,触发相应的回调. 整个过程分为以下几步 ...

  9. 深入理解Proxy 及 使用Proxy实现vue数据双向绑定

    阅读目录 1.什么是Proxy?它的作用是? 2.get(target, propKey, receiver) 3.set(target, propKey, value, receiver) 4.ha ...

随机推荐

  1. Rabbit MQ 基础入门

    Rabbit MQ 学习(一)基础入门 简介 RabbitMQ 简介 为什么选择 RabbitMQ RabbitMQ 的模型架构是什么? AMQP 协议是什么? AMQP 常用命令 概念 生产者和消费 ...

  2. 常用sign算法

    所有参数包括appkey或者token拼接成&key=value格式 转小写 正序排序 MD5后得到sign

  3. C++之关键字&标识符命名规则

    关键字 **作用:**关键字是C++中预先保留的单词(标识符) * **在定义变量或者常量时候,不要用关键字** C++关键字如下: 提示:在给变量或者常量起名称时候,不要用C++得关键字,否则会产生 ...

  4. ES6 学习 -- Promise对象

    1.promise含义:可以将promise对象看成是一个容器,它保存着未来才会结束的某个事件(一般是异步操作事件)的结果,各 种异步操作都可以用promise对象来处理promise的特点:(1)p ...

  5. flink流的执行大致流程图

  6. C# interface (接口基础知识详解)

    Interface(接口) (本文转载地址:http://blog.sina.com.cn/s/blog_574c993d0100d59n.html) 介绍:C#中的接口提供了一种实现运行时的多态.通 ...

  7. elast数据存放

    这几天一直在索引数据,突然发现服务器状态变红色了,去官网看了下 集群状态如果是红色的话表示有数据已经丢失了!这下头大了才索引了7G数据,后面还有10多个G, 我在liunx下看了下磁盘空间 发现运行e ...

  8. RAKsmart新出香港服务器的优势

    RAKsmart为了更好地服务用户,所以最近RAKsmart新推出得香港服务器又带给了用户更多的选择,那这次RAKsmart新推出香港服务器有哪些优势呢? 1.带宽更大可升至10Mpbs 香港服务器的 ...

  9. 单行文本截断 text-overflow

    div { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

  10. SQL Server - Store procedure 如何返回值

    存储过程 返回值 procedure return values : http://www.cnblogs.com/SunnyZhu/p/5542347.html return.select.outp ...