//Vue.js文件
class Vue {
constructor(el, data) {
this.el = document.querySelector(el);
// this._data = data;
this.data = data;
this.domPool = {}
this.init();
}
init() {
this.initData();
this.initDom()
}
initDom() {
this.bindDom(this.el)
this.bindInput(this.el)
console.log(this.domPool)
}
//初始数据 设置Object.defineProperty()
initData() {
const _this = this;
// this.data = {}
// for (let key in this._data) {
// Object.defineProperty(this.data, key, {
// get() {
// console.log('获取数据' + key)
// return _this._data[key]
// },
// set(newValue) {
// console.log('设置数据:', key, newValue)
// _this.domPool[key].innerHTML = newValue;
// _this._data[key] = newValue;
// }
// })
// }
//特殊,使用proxy
this.data = new Proxy(this.data, {
set(target, key, value, receiver) {
_this.domPool[key].innerHTML = value;
return Reflect.set(target, key, value)
},
get(target, key, receiver) {
return Reflect.get(target, key);
}
})
}
bindDom(el) {
const childNodes = el.childNodes;
childNodes.forEach(item => {
if (item.nodeType === 3) {
const _value = item.nodeValue;
if (_value.trim().length) { //去空格
let _isValid = /{{(.+?)}}/.test(_value)
if (_isValid) {
// console.log(item)
const _key = _value.match(/{{(.+?)}}/)[1].trim();
this.domPool[_key] = item.parentNode;
item.parentNode.innerText = this.data[_key] || undefined;
// console.log(item.nodeValue)
// console.log(_key)
}
}
}
item.childNodes && this.bindDom(item)
})
}
bindInput(el) {
const _allInputs = el.querySelectorAll('input');
_allInputs.forEach(input => {
const _vModel = input.getAttribute('v-model');
console.log(_vModel)
if (_vModel) {
input.addEventListener('keyup', this.handleInput.bind(this, _vModel, input), false)
}
})
}
handleInput(key, input) {
const _value = input.value;
this.data[key] = _value;
console.log(this.data)
}
setData(key, value) {
this.data[key] = value;
}
}
//index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数据的双向绑定01</title>
</head>
<body>
<div id="app">
<div>
姓名: <input type="text" v-model="name" name="name" id="name">
性别: <input type="text" v-model="gender" name="gender" id="gender">
邮箱: <input type="email" v-model="email" name="email" id="email">
</div>
<div>
<p>姓名:<span>{{name}}</span></p>
<p>性别:<span>{{gender}}</span></p>
<p>邮箱:<span>{{email}}</span></p>
</div>
<button id="btn">改变按钮</button>
</div>
</body>
<script src="mvvm.js"></script>
<script>
const app = new Vue('#app', {
name: '',
gender: '',
email: '',
})
document.querySelector('#btn').addEventListener('click', function () {
app.setData('name', '臭豆腐');
})
</script>
</html>