手写双向数据绑定(v-mode)

  • 使用Obiect.defineProperty() 实现双向数据绑定 vue2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>
</title>
</head>
<body>
<input type="text" id="input">
<p id="p"></p>
<script>
var input = document.getElementById('input')
var p = document.getElementById('p')
var obj={name: ""}
//当set或者get obj对象属性,就会触发事件
Object.defineProperty(obj, 'name', {
set: function(val){
//input.value = val
p.innerHTML = val
},
get: function(){
return val
}
})

//监听input的修改,并赋值给中间对象obj
input.addEventListener('input', function(e){
obj.name = e.target.value
})
</script>
</body>
</html>

  • 使用Proxy( ES6 的新特性) 和Reflect 实现双向数据绑定 vue3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>
</title>
</head>
<body>
<input type="text" id="input">
<p id="p"> </p>
<script>
var input = document.getElementById('input')
var p = document.getElementById('p')
var obj={}
//Reflect 可以用于获取可以获取对象对象的行为,它与Object类似,但更易读,为操作对象提供一种更优雅地 方式。它地方法与Proxy是对应的
let newProxy = new Proxy(obj, {
get: (target, key, recevier)=>{
return Reflect.get(target, key, recrvier)
},
set: (target, key, value, recevier)=>{
//监听newProxy是否有变化, 如果有则设置值
if(key == "text"){
input.value = val
p.innerHTML = value;
}
//将变化反射回原有对象
return Reflect.set(target, key, value, recevier)

}
})

//监听input的修改,并赋值给代理对象newProxy
input.addEventListener('input', function(e){
newProxy.text = e.target.value
})
</script>
</body>
</html>