响应基于 set 和 get(Object.defineProperty)

类型:

    单向绑定
双向绑定 简单例子(基于Object.defineProperty)
<!DOCTYPE html>

<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head> <body>
<div>
<form action="" class="form">
<div>
<label for="name">name</label>
<input type="text" name="name" id="name">
</div>
<div>
<label for="age">age</label>
<input type="text" name="age" id="age">
</div>
</form>
</div> </body>
<script>
// 实现Model到View的单向绑定
//Model
let person = {
data: {
name: '',
age: '',
}
};
//ViewModel
function binding(obj) {
for (let key in obj.data) {
Object.defineProperty(obj, key, {
get() {
console.log("getter");
return obj.data.key;
},
set(value) {
console.log("setter: " + value);
let dom = document.querySelector(`#${key}`);
dom.value = value;
console.log("dom.value: " + dom.value);
obj.data.key = value;
console.log("obj.data.key: " + obj.data.key);
},
});
}
} binding(person); // 实现view到model的单向绑定
//View
//获取表单对象
// let form = document.querySelector(".form"); // //监听form的input事件
// form.addEventListener('input', (e) => {
// let value = e.target.value;
// let name = e.target.getAttribute('name');
// person[name] = value;
// }); </script> </html>
分析:
1.js部分划分为数据(model)、关联视图方法viewModel 2.只需要使用binding方法,此方法就会遍历观测对象的所有key,并为key定义属性拦截器(Object.defineProperty),在数据set、get时定义额外的处理 3.特别地,在set的时候,不仅仅更新的观测对象的的值,还更新了DOM元素的值,当然这里是做了简单处理,用以了解响应设计基础部分,详细部分的话,有兴趣可以去看看官方源码设计 4.大家可能注意到有一个部分被我注释了,那个就是那个addEventListener这部分,这里实现了view到model的单向更新

总结: vue的响应式核心是基于ES5特性Object.defineProperty生成的set、get

Vue对数组和对象的观测处理:

    非根级变量响应方法:

        1.数组(vue对这些数组方法进行了代理,调用时做了更新视图的处理),至于为什么,下面马上解释

        检测边界:
1.增加或者修改 新增:vm.items[indexOfItem]=newValue
这种情况其实就是在为对象添加一个新key,数组本身也是Array类的一个实例 修改:vm.items[indexOfItem]=newValue按照数组本身是一个对象应该会触发更新,但是vue设计源码没有把数组对象的key进行set和get转换 2.修改长度 vm.items.length = newLength
同样这样没有set和get没法触发视图更新 另辟蹊径: 通过对原生方法进行改写来触发视图更新 1.变异方法(改变原数组) push()
pop()
shift()
unshift()
splice()
sort()
reverse() 2.非变异方法(返回新数组),vue在更新视图对这种覆盖原数组的情况作了优化处理,无需担心渲染效率 filter()
contact()
slice() 检测边界的新处理方法: 1.增加元素 1.1 按顺序插入 push(value)
unshift(value) 1.2 按指定key插入 Vue.$set(arr,index,value) 2.删除元素 splice(index,count) 3.修改元素 splice(index,1,value) 2.对象(遍历data赋予set和get) Vue.$set(target, key, value) 注意事项:被设置变量不能存在(源码发现key存在就会跳过此key的set和get转换) 增加单个属性 Vue.$set(target, key , value) 增加多个属性 Object.assign({},target,source)

最新文章

  1. Dynamics CRM导出数据到Excel
  2. HOLOLENS如何调节屏幕亮度和音量?
  3. Linux刷新DNS缓存
  4. The Pilots Brothers&#39; refrigerator(dfs)
  5. POJ 3616 Milking Time (排序+dp)
  6. C#百万数据查询超时问题
  7. node.js常用的几个模块总结
  8. linux之SQL语句简明教程---DISTINCT
  9. 云计算之路-阿里云上:部分服务器未及时续费造成docker swarm集群故障
  10. 微信小程序初探【类微信UI聊天简单实现】
  11. 自制无线共享工具C++源代码
  12. input[type=file]的美化
  13. 软件安装(ubuntu) --Linux基础编程
  14. intellij idea 快捷输出 main方法的规律
  15. AngularJs的MVC模式
  16. Swift 里 Array (二)初始化
  17. java8 - 3
  18. Qt5获取网卡/IP等信息
  19. JS中constructor与prototype关系概论
  20. django-DIL模板自定义过滤器,自定义标签,自定义包含标签

热门文章

  1. 【BZOJ4487】[JSOI2015]染色问题(容斥)
  2. Markdown温故知新(2):详解七大标准语法
  3. 香草js侦测元素是否离开视窗viewport
  4. tempermonkey文档及为google翻译添加清除输入框脚本
  5. 深入理解Session和Cookie的区别
  6. 联盟链IBM的超级账本Hyperledger Fabric框架,JP Morgan’s Quorum
  7. 学习笔记之Web
  8. CTF-PHP一句话木马
  9. PhoneGap架构基础及工作原理介绍
  10. 实验吧——忘记密码了(vim备份文件,临时文件(交换文件))