Vue.js 是采用 Object.defineProperty 的 getter 和 setter,并结合观察者模式来实现数据绑定的

当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。

用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

 
  Observer :数据监听器,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者,内部采用Object.defineProperty的getter和setter来实现
  Compile  :指令解析器,它的作用对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
  Watcher  :订阅者,作为连接 Observer 和 Compile 的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数
  Dep :消息订阅器,内部维护了一个数组,用来收集订阅者(Watcher),数据变动触发notify 函数,再调用订阅者的 update 方法

  从图中可以看出,当执行 new Vue() 时,Vue 就进入了初始化阶段,一方面Vue 会遍历 data 选项中的属性,并用 Object.defineProperty 将它们转为 getter/setter,实现数据变化监听功能;

  另一方面,Vue 的指令编译器Compile 对元素节点的指令进行扫描和解析,初始化视图,并订阅 Watcher 来更新视图, 此时Wather 会将自己添加到消息订阅器中(Dep),初始化完毕。

  当数据发生变化时,Observer 中的 setter 方法被触发,setter 会立即调用Dep.notify(),Dep 开始遍历所有的订阅者,并调用订阅者的 update 方法,订阅者收到通知后对视图进行相应的更新。

Vue.js 关于双向绑定的一些实现细节的更多相关文章

  1. vue.js 中双向绑定的实现---初级

    1. 1 我们看到的变量,其实都不是独立的,它们都是windows对象上的属性 <!DOCTYPE html> <html lang="en"> <h ...

  2. 原生js实现 vue的数据双向绑定

    原生js实现一个简单的vue的数据双向绑定 vue是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时 ...

  3. Vue框架之双向绑定事件

    Vue框架之双向绑定事件 首先介绍下Vue框架的语法 vue通过 {{temp}} 来渲染变量 {{count+100}} # 求和 v-text # 为标签插入text文本 v-html # 为标签 ...

  4. 用ES6的class模仿Vue写一个双向绑定

    原文地址:用ES6的class模仿Vue写一个双向绑定 点击在线尝试一下 最终效果如下: 构造器(constructor) 构造一个TinyVue对象,包含基本的el,data,methods cla ...

  5. 真正的原生JS数据双向绑定(实时同步)

    真正的原生JS数据双向绑定(实时同步) 接触过vue之后我感觉数据双向绑定实在是太好用了,然后就想着到底是什么原理,今天在简书上看到了一位老师的文章 js实现数据双向绑定 然后写出了我自己的代码 wi ...

  6. 用原生 JS 实现双向绑定及应用实例

    写在前面: 所谓的双向绑定,无非是从界面的操作能实时反映到数据,数据的变更也能实时展现到界面.angular封装了双向绑定的方法,使双向绑定变得十分简单.但是在有些场景下(比如下面那个场景),不能使用 ...

  7. 【前端】vue.js实现输入框绑定

    vue.js实现输入框绑定 实现效果如下: 实现代码及注释 <!DOCTYPE html> <html> <head> <title>vue.js数据动 ...

  8. 组件的通信 :provide / inject 对象进入后,就等于不用props,然后内部对象,直接复制可以接受数组,属性不能直接复制,可以用Object.assgin覆盖对象,或者Vue的set 双向绑定数据

    组件的通信 :provide / inject 对象进入后,就等于不用props,然后内部对象,直接复制可以接受数组,属性不能直接复制,可以用Object.assgin覆盖对象,或者Vue的set 双 ...

  9. Vue的数据双向绑定原理——Object-defineProperty

    一.定义 ①方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象. ②vue.js的双向数据绑定就是通过Object.defineProperty方法实现的,俗称属性拦截 ...

随机推荐

  1. 05_centos7安装python3

    https://www.cnblogs.com/FZfangzheng/p/7588944.html https://www.cnblogs.com/simuhunluo/p/7704765.html ...

  2. 边学边体验django--表格

    在模板的末尾,我们增加一个rlt记号,为表格处理结果预留位置. 表格后面还有一个{% csrf_token %}的标签.csrf全称是Cross Site Request Forgery.这是Djan ...

  3. 【题解】Mountain Walking-C++

    题目题意翻译题意简述:现在给一个N*N的矩阵,找一条路径从左上角走到右下角,每次可以向上下左右四个方向中某个方向走.要求走过的点中,数字最大的减去最小的.要求值越小越好.现在就是要求这个值. 输入格式 ...

  4. 031_检测 MySQL 服务是否存活

    #!/bin/bash#host 为你需要检测的 MySQL 主机的 IP 地址,user 为 MySQL 账户名,passwd 为密码#这些信息需要根据实际情况修改后方可使用 host=127.0. ...

  5. springboot项目:以run as-->spring boot app方式启动,配置热部署(亲测可用!!!)

    1.在pom.xml中添加热部署依赖 <!-- 热部署 --> <!-- devtools可以实现页面热部署(即页面修改后会立即生效, 这个可以直接在application.prop ...

  6. yum install 报错

    把python2升级到python3以后,yum报错: [root@localhost Python-]# yum install openssl File except KeyboardInterr ...

  7. android中的Section ListView

    前几天,和ios开发的同事扯淡时发现iphone里有个section listview,分章节的列表.android中的联系人也有这种效果,首字母相同的联系人会被分在一个章节中. 后来搜了一下,and ...

  8. 安装curl依赖库后yum不能使用问题解决

    安装curl 1)  进入/home目录下,解压curl-7.54.0.tar.gz [root@localhost home]# tar zxvf curl-7.54.0.tar.gz 2)  依次 ...

  9. pod package 生成 Framework

    pod package 生成 Framework pod package 是 cocoapods 的一个插件,如果没有的话使用以下命令安装: sudo gem install cocoapods-pa ...

  10. R-CNN/Fast R-CNN/Faster R-CNN

    一.R-CNN 横空出世R-CNN(Region CNN,区域卷积神经网络)可以说是利用深度学习进行目标检测的开山之作,作者Ross Girshick多次在PASCAL VOC的目标检测竞赛中折桂,2 ...