vue源码分析参考---2、数据代理
一、总结
一句话总结:
vue数据代理: data对象的所有属性的操作(读/写)由vm对象来代理操作
const vm = new MVVM({ el: "#test", data: { name: '张三2' } }) console.log(vm.name) // 读取的是data中的name, vm代理对data的读操作 vm.name = '李四2' // 数据保存到data中的name上, vm代理对data的写操作 console.log(vm.name, vm._data.name)
1、vue数据代理 好处?
通过vm对象就可以方便的操作data中的数据
2、vue数据代理 实现步骤?
a、通过Object.defineProperty(vm, key, {})给vm添加与data对象的属性对应的属性
b、所有添加的属性都包含get/set方法
c、在get/set方法中去操作data中对应的属性
二、数据代理和模板解析
博客对应课程的视频位置:
1. 说明
1) 分析 vue 作为一个 MVVM 框架的基本实现原理数据代理
模板解析
数据绑定
2) 不直接看 vue.js 的源码
3) 剖析 github 上某基友仿 vue 实现的 mvvm 库
4) 地址: https://github.com/DMQ/mvvm
2. 准备知识
1) [].slice.call(lis): 将伪数组转换为真数组
2) node.nodeType: 得到节点类型
3) Object.defineProperty(obj, propName, {}): 给对象添加/修改属性(指定描述符) configurable: true/false 是否可以重新 define
enumerable: true/false 是否可以枚举(for..in / keys())
value: 指定初始值
writable: true/false value 是否可以修改
get: 回调函数, 用来得到当前属性值
set: 回调函数, 用来监视当前属性值的变化
4) Object.keys(obj): 得到对象自身可枚举的属性名的数组
5) DocumentFragment: 文档碎片(高效批量更新多个节点)
6) obj.hasOwnProperty(prop): 判断 prop 是否是 obj 自身的属性
3. 数据代理
1) 数据代理: 通过一个对象代理对另一个对象(在前一个对象内部)中属性的操作(读/写)
2) vue 数据代理: 通过 vm 对象来代理 data 对象中所有属性的操作
3) 好处: 更方便的操作 data 中的数据
4) 基本实现流程
a. 通过 Object.defineProperty()给 vm 添加与 data 对象的属性对应的属性描述符
b. 所有添加的属性都包含 getter/setter
c. getter/setter 内部去操作 data 中对应的属性数据
数据代理示例代码
vue中
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>02_数据代理_vue</title> 6 </head> 7 <body> 8 9 <div id="test"></div> 10 <script type="text/javascript" src="js/vue.js"></script> 11 <script type="text/javascript"> 12 const vm = new Vue({ 13 el: "#test", 14 data: { 15 name: '张三' 16 } 17 }) 18 console.log(vm.name) // 读取的是data中的name, vm代理对data的读操作 19 vm.name = '李四' // 数据保存到data中的name上, vm代理对data的写操作 20 console.log(vm.name, vm._data.name) 21 22 23 </script> 24 </body> 25 </html>
mvvm中
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>02_数据代理</title> 6 </head> 7 <body> 8 9 <!-- 10 1. vue数据代理: data对象的所有属性的操作(读/写)由vm对象来代理操作 11 2. 好处: 通过vm对象就可以方便的操作data中的数据 12 3. 实现: 13 1). 通过Object.defineProperty(vm, key, {})给vm添加与data对象的属性对应的属性 14 2). 所有添加的属性都包含get/set方法 15 3). 在get/set方法中去操作data中对应的属性 16 --> 17 <div id="test"></div> 18 19 <script type="text/javascript" src="js/mvvm/compile.js"></script> 20 <script type="text/javascript" src="js/mvvm/mvvm.js"></script> 21 <script type="text/javascript" src="js/mvvm/observer.js"></script> 22 <script type="text/javascript" src="js/mvvm/watcher.js"></script> 23 <script type="text/javascript"> 24 const vm = new MVVM({ 25 el: "#test", 26 data: { 27 name: '张三2' 28 } 29 }) 30 console.log(vm.name) // 读取的是data中的name, vm代理对data的读操作 31 vm.name = '李四2' // 数据保存到data中的name上, vm代理对data的写操作 32 console.log(vm.name, vm._data.name) 33 34 35 </script> 36 </body> 37 </html>