# 数据响应式
目的: 是为了实现一个简易版本的vue
使用Proxy
进行数据劫持,实现了渲染数据和双向绑定的功能
<div id="app">
<p>{{msg}}</p>
<p>{{num}}</p>
<input v-model="num" />
</div>
// Vue的实现过程
class Vue extends EventTarget {
constructor(option){
super()
this.option = option
this._data = option.data
this.el = document.querySelector(option.el)
this.observe(this._data)
this.compileNode(this.el)
}
observe(data){
let _self = this
this._data = new Proxy(data, {
set(target, prop, newValue){
let event = new CustomEvent(prop, {
detail: newValue
})
_self.dispatchEvent(event)
return Reflect.set(...arguments)
}
})
}
compileNode(el){
let child = el.childNodes;
[...child].forEach(node => {
if(node.nodeType === 3){
let text = node.textContent
let reg = /\{\{\s*([^\s\{\}]+)\s*\}\}/g
if(reg.test(text)){
let $1 = RegExp.$1
Object.keys(this._data).includes($1) && (node.textContent = text.replace(reg, this._data[$1]))
this.addEventListener($1, e => {
node.textContent = text.replace(reg, e.detail)
})
}
}else if(node.nodeType === 1){
let attr = node.attributes
if(attr.hasOwnProperty('v-model')){
let key = attr['v-model'].nodeValue
node.value = this._data[key]
node.addEventListener('input', e => {
this._data[key] = node.value
console.log(this._data[key] )
})
}
this.compileNode(node)
}
})
}
}
// 使用Vue
let app = new Vue({
el:'#app',
data:{
msg:'Hello',
num:2
}
})
← vue相关