手撕v-model
2020年8月7日
Object.defineProperty
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
手写一个简单双向绑定<br />
<input type="text" id="model"><br />
<div id="modelText"></div>
</body>
<script type="text/javascript">
var user = {
name: '希染'
};
var defaultName = '希染'
var input = document.querySelector("#model");
var text = document.querySelector("#modelText");
input.value = user.name;
text.textContent = user.name;
// 数据到视图 model => view
Object.defineProperty(user, "name", {
get: function() {
console.log('获取user')
},
set: function(val) {
console.log('修改user')
input.value = val;
text.textContent = val;
}
})
// 视图到数据 view => model
input.addEventListener('input', function(val) {
user.name = input.value;
})
</script>
</html>
proxy
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" v-model="content">
<input type="text" v-model="content">
<h4 v-bind="content">dd</h4>
<input type="text" v-model="title">
<input type="text" v-model="title">
<h4 v-bind="title">数据改变</h4>
</body>
<script type="text/javascript">
function View() {
let proxy = new Proxy({}, {
get(obj, key) {
return obj[key]
},
set(obj, key, value) {
console.log(obj,key,value)
document.querySelectorAll(`[v-model="${key}"]`).forEach(item => {
item.value = value
})
document.querySelectorAll(`[v-bind="${key}"]`).forEach(item => {
item.innerHTML = value
})
},
})
document.querySelectorAll('[v-model]').forEach(item => {
item.addEventListener('keyup', function() {
proxy[this.getAttribute('v-model')] = this.value
})
})
}
new View()
</script>
</html>