浅聊vue双向绑定原理Object.defineProperty-/-Proxy
什么是双向绑定呢?vue又是怎么做的我们接下来就聊一聊
什么是双向绑定?
当数据模型data变化时,页面视图会得到响应更新
vue又是怎么做的?
vue其实现原理是对data的getter/setter方法进行拦截(Object.defineProperty或者Proxy),利用发布订阅的设计模式,在getter方法中进行订阅,在setter方法中发布通知,让所有订阅者完成响应。
说这些的时候我们在刚使用vue2.x的就会遇到过数据更新了啊,为何页面不更新呢。这其实就是Object.defineProperty在作祟。
而在vue3还没有发布时,很火的一个话题就是Vue3将使用Proxy 取代Vue2 版本的Object.defineProperty。那么Proxy
对比Object.defineProperty
有什么优势。
Proxy
对比Object.defineProperty
Proxy
- Proxy可以直接监听对象而非属性
- Proxy可以直接监听数组的变化
- Proxy有多达13种拦截方法,不限于apply、ownKeys、deleteProperty、has等等是Object.defineProperty不具备的
- Proxy返回的是一个新对象,我们可以只操作新的对象达到目的,不需要像Object.defineProperty一样遍历每个属性有一定的性能提升
- Proxy作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利
- Proxy直接实现对象属性的新增/删除
Object.defineProperty
Object.defineProperty只能劫持对象的属性,需要遍历对象的每一个属性,如果属性值也是对象,就需要递归进行深度遍历。
Object.defineProperty劫持的是对象的属性,所以新增属性时,需要重新遍历对象, 对其新增属性再次使用Object.defineProperty进行劫持。也就是Vue2.x中给数组和对象新增属性时,需要使用$set才能保证新增的属性也是响应式的, $set内部也是通过调用Object.defineProperty去处理的。
冷知识
Object.defineProperty无法监听数组数据的变化,但是为什么数组在使用push pop等方法的时候可以触发页面更新呢,那是因为vue内部拦截了这些方法。比如数组在使用push pop等方法的时候为什么可以触发页面更新呢,那是因为vue内部拦截了这些方法。
// 重写push等方法,然后再把原型指回原方法var ARRAY_METHOD = [ 'push', 'pop', 'shift', 'unshift', 'reverse', 'sort', 'splice' ];var array_methods = Object.create(Array.prototype);ARRAY_METHOD.forEach(method => {array_methods[method] = function () {// 拦截方法return Array.prototype[method].apply(this, arguments);}});
回归正题我们分别用代码简单的实现下Proxy
对比Object.defineProperty
如何实现绑定的
Object.defineProperty实现
// 这是将要被劫持的对象
const data = {name: '',
};
// 遍历对象,对其属性值进行劫持
Object.keys(data).forEach(function(key) {console.log('1')Object.defineProperty(data, key, {enumerable: true,configurable: true,get: function(newVal) {return val},set: function(newVal) {// 当属性值发生变化时我们可以进行额外操作console.log(`大家好,我是${newVal}我被劫持了`);val = newVal;},});
});
data.name = '111';
Proxy实现
const target = {name: '控制'
};const handler = {get: function(target, key) {console.log(`${key} 被读取`);return target[key];},set: function(target, key, value) {console.log(`${key} 被设置为 ${value}`);target[key] = value;}
};const testObj = new Proxy(target, handler);console.log(testObj.name); // name 被读取 及输出名字 控制
testObj.name = 1; // name 被设置为 1 输出 1
Proxy参数介绍
1.get(target, propKey, receiver)
该方法的含义是:用于拦截某个属性的读取操作。它有三个参数,如下解析:
- target: 目标对象。
- propKey: 目标对象的属性。
- receiver: (可选),该参数为上下文this对象
2.set(target, propKey, value, receiver)
该方法是用来拦截某个属性的赋值操作,它可以接受四个参数,参数解析分别如下:
- target: 目标对象。
- propKey: 目标对象的属性名
- value: 属性值
- receiver(可选): 一般情况下是Proxy实列
3.has(target, propKey)
该方法是判断某个目标对象是否有该属性名。接收二个参数,分别为目标对象和属性名。返回的是一个布尔型。
- target: 目标对象。
- propKey: 目标对象的属性名
4.construct(target, args, newTarget)
该方法是用来拦截new命令的,它接收三个参数,分别为 目标对象,构造函数的参数对象及创造实列的对象。
第三个参数是可选的。它的作用是拦截对象属性。
- target: 目标对象。
- args: 构造函数的参数对象
- newTarget:创造实列的对象
5.apply(target, object, args)
该方法是拦截函数的调用的。该方法接收三个参数,分别是目标对象。目标对象上下文this对象 和 目标对象的数组;它和 Reflect.apply参数是一样的
第三个参数是可选的。它的作用是拦截对象属性。
- target: 目标对象。
- object: 目标对象上下文this对象
- args:目标对象的数组
写在最后的话大家不要忘记,点赞,评论,收藏
浅聊vue双向绑定原理Object.defineProperty-/-Proxy相关推荐
- 浅谈vue双向绑定原理
简析mvvm框架 目前angular,reat和vue都是mvvm类型的框架 以vue为例 这里的vm 就是vue框架,它相当于中间枢纽的作用,连接着model 和view. 当前台显示的view发生 ...
- vue双向绑定原理及实现
vue双向绑定原理及实现 一.MVC模式 二.MVVM模式 三.双向绑定原理 1.实现一个Observer 2.实现一个Watcher 3.实现一个Compile 4.实现一个MVVM 四.最后写一个 ...
- 【vue双向绑定原理浅析】
vue双向绑定原理浅析 1.什么是双向绑定? 所谓双向绑定,指的是vue实例中的data与其渲染的DOM元素的内容保持一致,无论谁被改变,另一方会相应的更新为相同的数据.(数据变化更新视图,视图变 ...
- 前端技巧|vue双向绑定原理,助你面试成功
在面试一些大厂的时候,面试官可能会问到你vue双向数据绑定的原理是什么?有些小伙伴不知道是什么东西,这样你在面试官的眼里就大打折扣了.今天小千就来给大家介绍一下vue的双向绑定原理,千万不要错过啦. ...
- Vue双向绑定原理代码实现
1.代码实现Vue双向绑定与事件绑定,v-bind v-model v-on DOM结构准备 <body><div id="app"><form> ...
- Vue2双向绑定,Object.defineProperty、Observe、Compile、Watcher、Dep各显神通,相辅相成
这个问题真的可以说是一个好问题,毕竟基本上面试时也总会被问到,一问双向绑定原理怎么回事儿啊?就说,用了Object.defineProperty()做得数据劫持,劫持了get()和set(),然后巴拉 ...
- Vue的数据双向绑定和Object.defineProperty()
Vue是前端三大框架之一,也被很多人指责抄袭,说他的两个核心功能,一个数据双向绑定,一个组件化分别抄袭angular的数据双向绑定和react的组件化思想,咱们今天就不谈这种大是大非,当然我也没到达那 ...
- 浅谈vue双向绑定的原理
一.什么是双向绑定 我们先从单向绑定切入 单向绑定非常简单,就是把Model绑定到View,当我们用JavaScript代码更新Model时,View就会自动更新 双向绑定就很容易联想到了,在单向绑定 ...
- 通俗易懂了解Vue双向绑定原理及实现
https://www.cnblogs.com/wangjiachen666/p/9883916.html 亲测可用
最新文章
- myeclipse新建或者另存为新jsp无法打开
- 1001.Reverse Root
- spring-boot基础概念与简单应用
- itextpdf添加表格元素_itext生成pdf文件-表格
- c++ eos智能合约开发_hyperledger fabric 开发第一个智能合约
- 【OCP|052】OCP题库更新,052最新考题及答案整理-第10题
- 鸿蒙对抗谷歌,华为下定决心对抗谷歌,打出第一张王牌,鸿蒙系统更进一步
- mongodb adminmongo 使用过程中的一些小问题记录
- 深入理解Core Data
- 优化网站设计(九):减少DNS查找的次数
- python基础之函数式编程
- 验证服务器的通用性,通用VNFM部署的可行性分析与验证
- python实现pdf转ppt_wps中pdf转成word文档 Python转换PPT为PDF
- 数据挖掘(一)-探索性数据分析
- mysql db_owner_SQL Server修改数据库对象所有者(Owner)浅析
- 麒麟v10安装达梦数据库
- 详解C++学习方向和就业方向!
- (FortiGate)飞塔防火墙产品参数
- 人人都有发言权的新媒体时代 内容审核需亮剑
- 智慧城市建设,目前所面临的技术瓶颈是什么?