vue数据双向绑定实现
1.vue2.0数据劫持defineProperty之后,结合发布订阅这模式
缺点:不能监听数组变化,必须遍历对象的每个属性,必须深层遍历嵌套的对象
2.vue3.0数据代理proxy 可以直接监听对象,数组(而非属性)
简单实现,通过Object对象的 defineProperty属性,重写data的get和set方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- 视图 --> <div id="app"> <h1>{{msg}}</h1> </div> <script> // 模板 let data = { msg: 'hello msg', _data: {} } // 设置特性 Reflect.defineProperty(data, 'msg', { // 取值器 get() { console.log('get', this, arguments); // 获取备份对象 return this._data.msg; }, // 赋值器 set(val) { console.log('set', this, arguments); // 设置备份对象 this._data.msg = val; //视图显示 updataView(this._data); } }) let tpl = document.getElementById('app').innerHTML; function updataView(data) { let html = tpl.replace(/{{(\w+)}}/, (match, $1) => { return data[$1]; }) document.getElementById('app').innerHTML = html; } // 设置 触发赋值器 data.msg = 'hello world'; // 读取 触发取值器 console.log(data.msg); </script> </body> </html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" id="username"/>
<p id="uName"></p>
<script>
let obj = {}
Object.defineProperty(obj, 'username', {
// 取值
get: function() {
console.log('取值');
},
set: function(val) {
console.log('设置值');
document.getElementById('uName').innerText = val;
}
})
document.getElementById('username').addEventListener("keyup", function(){
//event
obj.username = event.target.value;
})
</script>
</body>
</html>

浙公网安备 33010602011771号