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詳解