Vue的双向数据绑定原理--简单案例直接get到
程序员文章站
2022-07-12 21:56:46
...
前言
虽然写项目的话可能会用不着,但要是面试的话会问哪
提问: Vue 中双向数据绑定是如何实现的? ||
关键词:“代理”、“Object.defineProperty(vue2)”、“Proxy(vue3)”
核心:数据订阅、数据劫持(代理)
一、实现方法和原理
- Object.defineProperty(vue2)和 Proxy(vue3)
-
不同点
- vue2中实现双向绑定的原理,采用的是
es5
中的Object.defineProperty这个方法来实现的 - 在vue3中则是采用
Proxy
这个对象来实现的
- vue2中实现双向绑定的原理,采用的是
-
相同点
- 虽然说两者实现的方法是不一样的,但是在
流程
上,包括含义
上是非常像的。都是通过代理
的方式来实现双向数据绑定
- 虽然说两者实现的方法是不一样的,但是在
-
不同点
- (以vue2为例)当把一个普通的JavaScript对象传给Vue实例的data选项,Vue将遍历此对象所有的属性,使用Object.defineProperty把这些属性全部转为getter(获取)/setter(设置)。(getter和setter相当于两个代理,一个代理我们获取数据,另一个代理我们设置数据)
二、 示例
// es5中提供的方法
Object.defineProperty(obj, prop, descriptor)
// 方法会直接在一个对象(obj)上定义一个新属性,或者修改一个对象的现有属性(prop),并返回此对象。
// 应当直接在Object构造器对象上调用此方法,而不是在任意一个Object类型的实例上调用。
- 这个方法有三个参数
obj
要定义属性的对象。
prop
要定义或修改的属性的名称 。
descriptor
如何定义或修改这属性
要定义的选项,“{ }”。在这里面设置getter和setter。
- 实例(以es5为例)
<div id="app">
<div>
<input type="text" id="ipt" oninput="changeData(this)">
</div>
<div>
<div id="main"></div>
</div>
</div>
<script>
// 1、数据初始化,等同与vue中的data属性
var data ={
msg:"数据的双向绑定"
}
// 2、显示页面上的数据(原生js)
document.getElementById("ipt").value = data.msg
document.getElementById("main").innerText = data.msg
// 3、产生双向数据绑定需要的代理
// 采用obj.msg代理data.msg 当获取obj.msg时实质上是获取data.msg, 设置obj.msg实质上是设置data.msg
var obj={}
Object.defineProperty(obj,'msg',{
// 产生getter(代理获取者)和setter(代理设置者)
get:function(){
// 获取obj.msg时实质上是获取data.msg
return data.msg
},
// 形参val是需要设置给data.msg的值
set:function(val){
// 设置obj.msg实质上是设置data.msg
data.msg = val
// 判断程序是否走了set ,输出data
console.log(data.msg);
}
})
// 4、input事件的处理程序
function changeData(a){
// 调用代理去设置数据
obj.msg= a.value
// 更新下方div的显示
document.getElementById("main").innerText = obj.msg
}
</script>
- 流程梳理
- 执行input输入时,触发
input
事件 - 触发事件后在走
obj.msg=a.value
(原来obj中没有msg) - 后触发 Object.defineProperty(obj,‘msg’,{})定义一个msg
- 当input事件改变
obj.msg
时 程序走 其代理方法中的get
(执行get时给data.msg赋值,此时参数val为a.value) 当获取obj.msg中的值时,程序走set(而set执行后返回的是data.msg)
- 执行input输入时,触发
上一篇: AcWing 479 加分二叉树