学习手写v-model
<body>
<div id="app">
<div>
<span>用户</span>
<input type="text" v-model="username" placeholder="用户" />
<span>密码</span>
<input type="text" v-model="password" placeholder="密码" />
<span>手机</span>
<input type="text" v-model="phone" placeholder="手机" />
</div>
<div>
<span>用户: <span>{{ username }}</span></span>
</div>
<div>
<span>密码: <span>{{ password }}</span></span>
</div>
<div>
<span>手机: <span>{{ phone }}</span></span>
</div>
</div>
<button class="btn">点我</button>
</body>
<script src="./MVVM.js"></script>
<script>
document.querySelector('.btn').addEventListener('click', () => {
app.setValue('phone', '214122321321')
})
const obj = {
username: '',
password: '',
phone: '',
}
const app = new MVVM('#app', obj)
</script>
下面是js部分
// 手写v-model
const varibleReg = /{{(.+?)}}/
// 1 先实现数据劫持
// 2 绑定input
// 3 渲染dom节点内容
class MVVM {
constructor(el, data) {
this.el = document.querySelector(el)
this._data = data
this.domPool = {}
this.init()
}
setValue(key, value) {
this.data[key] = value
}
bindInput(el) {
const inputs = el.querySelectorAll('input[v-model]')
inputs.forEach(input => {
input.addEventListener('input', this.handleInput.bind(this, input))
})
}
handleInput(input) {
const key = input.getAttribute('v-model')
const _value = input.value
this.data[key] = _value
}
bindDom(el) {
const childNodes = el.childNodes
childNodes.forEach(item => {
const _value = item?.nodeValue
if (item?.nodeType === 3 && varibleReg.test(_value)) {
const key = _value.match(varibleReg)[1].trim()
this.domPool[key] = item.parentNode
item.parentNode.innerText = this.data[key]
}
// 递归函数
!!item?.childNodes.length && this.bindDom(item)
})
}
initData() {
this.data = {}
for (const key in this._data) {
Object.defineProperty(this.data, key, {
get: () => this._data[key],
set: newVal => {
this._data[key] = newVal
this.domPool[key].innerText = this.data[key]
}
})
}
}
init() {
this.initData()
this.bindDom(this.el)
this.bindInput(this.el)
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。