vue是通过Object.defineProperty()来实现数据劫持的,主要使用了它的set和get属性,如果对其不熟悉的话,请点击这里阅读更多用法。
在下面的例子中可以清晰看出其使用方法:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>VUE双向绑定</title>
</head>
<body>
姓名: <input type="text" name="" id="" v-model="name" placeholder="name">
姓名: <input type="text" name="" id="" v-model="name" placeholder="name" disabled>
<p>name: <span v-text="name"></span></p>
性别: <select name="" id="" v-model="sex">
<option value="男">男</option>
<option value="女">女</option>
</select>
<p>性别: <span v-text="sex"></span></p>
<script>
class Vue {
constructor(opt) {
let data = opt.data || {},
keys = Object.keys(data),//获取传入data的所有属性
_this = this;
this.data = {};
//添加this.data的监听属性
keys.forEach(item => {
Object.defineProperty(this.data, item, {
//在读取name属性这个值触发的函数
get: function () {
return this[`_${item}`];
},
//在设置name属性这个值触发的函数
set: function (value) {
this[`_${item}`] = value;
_this.render(item);
}
});
});
//对this.data设置属性值
for (let item in data) {
this.data[item] = data[item];
//在此处触发set函数
}
this.input();
}
//设置数据的显示
render(prot) {
document.querySelectorAll(`[v-model=${prot}]`).forEach(el => {
el.value = this.data[prot];//此处出发get函数
});
document.querySelectorAll(`[v-text=${prot}]`).forEach(el => {
el.innerText = this.data[prot];//此处出发get函数
});
}
//对文本框进行输入监听
input() {
document.querySelectorAll(`[v-model]`).forEach(el => {
el.oninput = () => {
this.data[el.getAttribute('v-model')] = el.value;//在此处触发set函数
};
});
}
}
//创建Vue实例
const vm = new Vue({
data: {
name: '张三',
sex: '男'
}
})
</script>
</body>
</html>
简单实现了VUE的数据双向绑定,当然了,里面的v-model和vue的里面的实现原理是不一样的,仅仅为了达到v-model的功能。
想知道vue里面v-model的原理请跳转至v-model详解