1、如何实现双向绑定?

以用户提交表单为例,其原理是我们对input进行value的属性绑定(v-bind:value="…"),将Model中的变量绑定到View上(Model -> View),以及当用户对input进行操作时,进行事件监听(v-on: input =" … "),从而实现双向数据绑定。v-model实际上是语法糖,结合了上述两个操作。

2、底层原理是什么?

参考:Vue的MVVM是如何实现的
如何追踪数据变化?
Vue将遍历传入Vue实例data选项中的js对象的所有property,并使用Object.defineProperty 把这些 property 全部转为getter/setter。这些getter/setter可使property在被访问和修改时通知变更。每个组件实例都对应一个watcher实例,它会在组件渲染的过程中把“接触”过的数据property记为依赖,之后当依赖项的setter触发时,会通知watcher,从而使它关联的组件重新渲染。

vue实现数据双向绑定主要是采用数据劫持,配合发布-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter和getter,在数据变动时发布消息给订阅者,触发响应监听回调。
vue数据双向绑定整合Observer Compile 和 Watcher三者,

(1) 通过Observer来监听自己Model的数据变化: Obeject.defineProperty()来监听属性变动,将需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上setter和getter,同时创建一个消息订阅器Dep用来收集订阅者,数据变动之后触发notify,再调用订阅者的update方法
(2) 通过Complie来解析编译模板指令: 对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图。(每次找到一个数据替换,都要重新渲染一遍,可能会造成页面的回流和重绘,那么我们最好的办法就是把以上的元素放在内存中,在内存中操作完成之后,再替换掉.)
(3) **通过Watcher搭起Observer 和Compile 之间的通信桥梁:**能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图,达到 数据变化 -> 视图更新,视图交互变化 -> 数据model变更。什么时候添加绑定watcher? 当订阅数据变化时,来绑定更新函数,从而让watcher更新视图

(1)观察者模式和发布订阅者模式的区别


**观察者模式:**在观察者模式里,被观察者subject只需要维护一套观察者observer的集合,这些observer实现相同的接口,subject只需要知道,通知observer时,需要调用哪个方法就好了。观察者模式是由具体目标调度的,其订阅者与发布者之间存在依赖。
发布订阅者模式: :发布订阅模式里,不仅仅只有发布者和订阅者两个角色,还存在一个调度中心,当事件触发时,发布者发布该事件到调度中心(顺带上下文),由调度中心统一调度订阅者注册到调度中心的处理代码。发布/订阅模式是统一由调度中心调的,其订阅者与发布者之间不存在依赖

(2)Object.defineProperty可以对数组对象数据进行劫持吗?数组对象如何实现数据的响应更新?

参考:深入理解 Object.defineProperty 及实现数据双向绑定

Object.defineProperty(obj, prop, descriptor);

descriptor由两部分组成:数据描述符(configurable,enumerable,value 及 writable 配置项)和访问器描述符(configurable,enumerable,get以及set),即使用访问器描述符中 getter或 setter方法的话,不允许使用 writable 和 value 这两个配置项。

ans:

  1. 当我们使用 Object.defineProperty 对数组赋值有一个新对象的时候,会执行set方法,但是当我们改变数组中的某一项值的时候,或者使用数组中的push等其他的方法,或者改变数组的长度,都不会执行set方法
  2. 通过重写 Array.property.push方法,并且生成一个新的数组赋值给数据,这样数据双向绑定就触发了
    重新编写数组的方法:
const arrPush = {};// 如下是 数组的常用方法
const arrayMethods = ['push','pop','shift','unshift','splice','sort','reverse'
];
// 对数组的方法进行重写
arrayMethods.forEach((method) => {const original = Array.prototype[method]; arrPush[method] = function() {console.log(this);return original.apply(this, arguments);}
});const testPush = [];
// 对 testPush 的原型 指向 arrPush,因此testPush也有重写后的方法
testPush.__proto__ = arrPush;testPush.push(1); // 打印 [], this指向了 testPushtestPush.push(2); // 打印 [1], this指向了 testPush
(3)Object.defineProperty和Proxy的区别

Object.definePropery是对对象的属性的劫持,而Proxy是对对象的劫持,因此对于新增的属性不用重新定义getter,setter特性,Proxy也可以实现劫持,同时对于复杂对象也不必进行深度遍历。Vue3中将使用Proxy来实现数据劫持.
参考:Object.defineProperty与Proxy理解整理

let p = new Proxy(target, handler)
  1. Object.defineProperty()的主要问题

    • 不能监听数组的变化
    • 必须遍历对象的每个属性
    • 必须深层遍历嵌套的对象
  2. Proxy
    • 针对对象:针对整个对象,而不是对象的某个属性。相比于Object.defineProperty(),省了一个 Object.keys() 的遍历
    • 支持数组:不需要对数组的方法进行重载
    • 嵌套支持:和 Object.defineProperty() 是一样的,也需要通过逐层遍历来解决。Proxy 的写法是在 get 里面递归调用 Proxy 并返回
  3. Proxy的优劣势
    • 优势:Proxy 的第二个参数可以有 13 种拦截方法,比 Object.defineProperty() 要更加丰富
    • 劣势:Proxy 的兼容性不如 Object.defineProperty(), 不能使用 polyfill 来处理兼容性

如何实现双向绑定?底层原理是什么?相关推荐

  1. [vue] 什么是双向绑定?原理是什么?

    [vue] 什么是双向绑定?原理是什么? 双向数据绑定个人理解就是存在data→view,view→data两条数据流的模式.其实可以简单的理解为change和bind的结合.目前双向数据绑定都是基于 ...

  2. vue数据双向绑定的原理

    vue数据双向绑定的原理 一 复习闭包 1 闭包含义: 当函数嵌套时,内部函数使用了外部函数的变量,就会产生闭包 当函数可以记住并访问自己的作用域时,就会产生闭包 2 闭包注意点 ① 队列里的代码执行 ...

  3. Vue双向绑定:原理篇(详细)

    文章目录 前言 什么是响应式 数据劫持 发布者-订阅者模式 模式简介 发布者 Observer 订阅器 dep 订阅者 Watcher 整体流程 初始化data data变为响应式数据 解析模板 收集 ...

  4. vue双向绑定的原理

    之前我有个学生在面试的时候,面试官问vue的双向绑定如何实现?学生说用v-module实现.又问那么双向绑定的原理是什么?就回答不上来了,这个offer工资在18k左右,其他问题都回答上来了,如果这个 ...

  5. VUE双向绑定的原理(简单版)+虚拟DOM 节点的创建和更新

    手动敲敲代码,就很容易理解了,供参考 1.以下是VUE双向绑定的原理(简单版) 主要是监听和defineProperty实现简单的双向绑定 <html><head></h ...

  6. 浅谈vue双向绑定的原理

    一.什么是双向绑定 我们先从单向绑定切入 单向绑定非常简单,就是把Model绑定到View,当我们用JavaScript代码更新Model时,View就会自动更新 双向绑定就很容易联想到了,在单向绑定 ...

  7. DataBinding的双向绑定实现原理

    " 悄悄咪咪告诉你,DataBinding是怎么实现双向绑定的" 在讲DataBinding之前,有必要讲讲ViewBinding 1.ViewBinding 1) 配置 要使用V ...

  8. Vue学习笔记--Vue双向绑定实现原理

    我们知道Vue可以实现数据双向绑定,Angular和Vue都是采用的MVVM 模式,意思就是当M(模型层)层数据进行修改时,VM层会监测到变化,并且通知V(视图层)层进行相应的修改,反之修改V层则会通 ...

  9. vue2数据双向绑定的原理

    vue2的数据双向绑定原理使用的是es5的数据劫持object.defineProperty,如果读取数据就会触发get,修改数据就会触发set,达到数据和视图的响应和更新,但是因为js固有的特性,不 ...

  10. php 双向绑定的原理,【原】数据双向绑定和虚拟dom探究

    自各个mvvm框架出现和流行以来,他们都实现了两个新的概念及功能:数据双向绑定和虚拟dom.网上对于这两个概念的阐述很多很全面,这里仅对它们的原理和应用场景进行探究和记录,希望更接地气的理解和应用这两 ...

最新文章

  1. Activity(3、启动模式)
  2. python语言入门电子版-python从入门到精通pdf
  3. 黑马lavarel教程---13、分页
  4. Kafka解惑之Old Producer(3)——Async Analysis
  5. linux yum自动挂载_LINUX6安装YUM仓库和实现开机自动挂载
  6. ajax表单提交post(错误400) 序列化表单(post表单转换json(序列化))
  7. DB2中修改表字段类型或者长度
  8. 2019年数据库系统工程师上午真题及答案解析
  9. verilog学习笔记——8位数码管驱动设计与验证
  10. 解决 fxp/composer-asset-plugin 包报错问题
  11. 服务器系统 与win7系统,服务器系统win7
  12. MySQL 修改报错 You can't specify target table 'tb_trade' for update in FROM clause
  13. 联想服务器能够上固态硬盘吗,联想Y400能不能装固态硬盘 需要什么接口的
  14. Android实现语音识别成中文
  15. 防近视护眼台灯哪个牌子好?无蓝光无频闪的护眼台灯推荐
  16. 云服务器与虚拟主机有什么区别,我们应该如何选择?
  17. 数学之美读书感悟03
  18. Apple App Store 音乐App 美国畅销榜单前30名使用记录
  19. [SDIO]Read Wait 读等待机制
  20. Google Voice 保留号码

热门文章

  1. vi/vim简介及使用教程
  2. 【matlab】函数meshgrid的用法详解(生成网格矩阵)和ndgrid的区别及用法
  3. 奇点临近:人工智能让人类变成软件,并迅速统治宇宙
  4. 可解释性神经网络——1.xNN
  5. SA markdown
  6. 前端上传文件或者上传文件夹
  7. 【观察】亚信科技:中期业绩逆势上扬,让5G新价值挺进纵深
  8. 小学生也能看懂的海伦公式推导
  9. Html(快捷键!+Tab)
  10. 【学习设计模式6】单枪匹马只身一人——单例模式