Vue系列二十四:源码解析-数据绑定
数据劫持与数据绑定
1、数据绑定(model==>View):
(1)、一旦更新了data中的某个属性数据, 所有界面上直接使用或间接使用了此属性的节点都会更新(更新)。
2、数据劫持
(1)、数据劫持是vue中用来实现数据绑定的一种技术。
(2)、基本思想: 通过defineProperty()来监视data中所有属性(任意层次)数据的变化, 一旦变化就去更新界面。
3、四个重要对象
(1)、Observer
用来对data所有属性数据进行劫持的构造函数。
给data中所有属性重新定义属性描述(get/set)。
为data中的每个属性创建对应的dep对象。
(2)、Dep(Depend)
data中的每个属性(所有层次)都对应一个dep对象。
创建的时机:
在初始化define data中各个属性时创建对应的dep对象。
在data中的某个属性值被设置为新的对象时。
对象的结构:
{ id, // 每个dep都有一个唯一的id subs //包含n个对应watcher的数组(subscribes的简写) }
subs属性说明:
当一个watcher被创建时, 内部会将当前watcher对象添加到对应的dep对象的subs中。
当此data属性的值发生改变时, 所有subs中的watcher都会收到更新的通知, 从而最终更新对应的界面。
(3)、Compile
用来解析模板页面的对象的构造函数(一个实例)。
利用compile对象解析模板页面。
每解析一个表达式(非事件指令)都会创建一个对应的watcher对象, 并建立watcher与dep的关系。
complie与watcher关系: 一对多的关系。
(4)、Watcher
模板中每个非事件指令或表达式都对应一个watcher对象。
监视当前表达式数据的变化。
创建的时机: 在初始化编译模板时。
对象的组成:
{ vm, //vm对象 exp, //对应指令的表达式 cb, //当表达式所对应的数据发生改变的回调函数 value, //表达式当前的值 depIds //表达式中各级属性所对应的dep对象的集合对象 //属性名为dep的id, 属性值为dep }
(5)、 总结: dep与watcher的关系: 多对多
一个data中的属性对应对应一个dep, 一个dep中可能包含多个watcher(模板中有几个表达式使用到了属性)。
模板中一个非事件表达式对应一个watcher, 一个watcher中可能包含多个dep(表达式中包含了几个data属性)。
数据绑定使用到2个核心技术:
defineProperty()
消息订阅与发布
4、双向数据绑定
(1)、双向数据绑定是建立在单向数据绑定(model==>View)的基础之上的。
(2)、双向数据绑定的实现流程:
在解析v-model指令时, 给当前元素添加input监听
当input的value发生改变时, 将最新的值赋值给当前表达式所对应的data属性
<body> <!-- 1. 数据绑定 * 初始化显示: 页面(表达式/指令)能从data读取数据显示 (编译/解析) * 更新显示: 更新data中的属性数据==>页面更新 --> <div id="test"> <p>{{name}}</p> <p v-text="name"></p> <p v-text="wife.name"></p> <button v-on:click="update">更新</button> </div> <!-- Dep 创建时间:初始化的给data的属性进行数据劫持时创建的 个数:与data中的属性一一对应 Dep的结构: id: 标识 subs:[] n个相关的watcher对象的容器 Watcher 创建时间:初始化的解析大括号表达式与一般指令时创建 个数:与模板中表达式(不包含事件指令)一一对应 Watcher的结构: this.cb = cb; // 用于更新界面的回调 this.vm = vm; // vm this.exp = exp; // 对应表达式 this.depIds = {}; // 相关的n个dep的容器对象 this.value = this.get(); // 当前表达式对应的value Dep与Watcher之间的关系:多对多关系 一个dep中对应多个watcher:同一个属性在模板中多次使用 {{name}} v-text="name" 一个watcher中对应多个dep:多层表达式 {{a.b.c}} 建立关系的方法:data中属性的get()方法 建立时间:初始化的解析模块中的表达式创建watcher对象时 vm.name = 'xxx' 执行流程: 1、data中的name属性值变化 2、调用name的set()方法 3、通知dep 4、通知所有相关的watcher 5、调用cb()回调函数 6、调用updater方法更新界面 --> <script type="text/javascript" src="js/mvvm/compile.js"></script> <script type="text/javascript" src="js/mvvm/mvvm.js"></script> <script type="text/javascript" src="js/mvvm/observer.js"></script> <script type="text/javascript" src="js/mvvm/watcher.js"></script> <script type="text/javascript"> new MVVM({ el: '#test', data: { name: 'feifei', wife: { name: 'feifei2', age: 28 } }, methods: { //更新数据 update () { this.name = 'xinxin' } } }) </script> </body>
<body> <div id="test"> <input type="text" v-model="msg"> <p>{{msg}}</p> </div> <script type="text/javascript" src="js/mvvm/compile.js"></script> <script type="text/javascript" src="js/mvvm/mvvm.js"></script> <script type="text/javascript" src="js/mvvm/observer.js"></script> <script type="text/javascript" src="js/mvvm/watcher.js"></script> <script type="text/javascript"> new MVVM({ el: '#test', data: { msg: 'hello' } }) </script> </body>
- vue源码解析之--数据双向绑定
- Vue.js解析(三)【从Vue.js源码角度再看数据绑定】
- Silverlight实用窍门系列:8. Accordion模拟菜单,Accordion动态绑定数据,模拟菜单点击【附带源码实例】
- 小猿圈解析vue数据双向绑定的缺陷
- 从Vue.js源码角度再看数据绑定
- Vue双向数据绑定原理解析
- 从Vue.js源码角度再看数据绑定
- vue数据双向绑定原理解析(get & set)
- 从源码角度学习vue数据绑定
- 通过源码分析Vue的双向数据绑定详解
- vue数据双向绑定源码,3个版本由简到难
- Vue源码解析(二)Vue的双向绑定讲解及实现
- vue.js双向数据绑定原理解析及模拟demo的实现
- vue数据控制视图源码解析
- Redis源码分析系列二十四: 7 set---setCommand解析
- Vue源码学习(一)———数据双向绑定 Observer
- Vue学习之源码分析--从Vue.js源码角度再看数据绑定(三)
- JavaScript设计模式系列05_观察者模式(发布订阅)写的数据联动(类似于vue的数据绑定)
- Silverlight实用窍门系列:5.绑定webService数据到DataGrid,设置DataGrid模板,模拟数据库数据的绑定【附带实例源码】
- Vue双向数据绑定原理解析