理念:
1、将所有data数据交给object.defineProperty进行set个get监听
2、初始化vue对象的时候,需要将对应的data,el赋值给当前的this对象
3、对html关联的el对象进行监听,对于v-model属性进行input监听,如果有输入就添加watch对象
3、对html关联的el对象进行监听,对于v-text属性进行innnerHtml监听,如果有输入就添加watch对象
4、创建watch对象,查看是否有数据更新
constructor(options) {
this.options = options
this.$data = options.data()
this.__watchers = {}
// 创建观察者
this.Observer(this.$data)
}
mount (el) {
this.$el = document.querySelector(el)
// 进行模版监听
this.Compire(this.$el)
}
Observer (data) {
for (const key in data) {
this.__watchers[key] = []
if (Object.hasOwnProperty.call(data, key)) {
// 获取到data对应的值
let element = data[key];
const watch = this.__watchers[key]
Object.defineProperty(this.$data, key, {
set: function (newVal) {
if (newVal !== element) {
element = newVal
}
// 通知他的观察者去更新数据
console.log(watch.length)
watch.forEach(watcher => {
watcher.update()
});
},
get: function () {
return element
}
})
}
}
}
Compire (el) {
let nodes = el.children
for (let index = 0; index < nodes.length; index++) {
const node = nodes[index];
if (node.hasAttribute('v-model')) {
let attr = node.getAttribute('v-model')
console.log(attr)
console.log(this.__watchers[attr])
this.__watchers[attr].push(new Watch(node, this, attr, 'value'))
node.addEventListener('input', () => {
this.$data[attr] = node.value
})
}
if (node.hasAttribute('v-text')) {
let attr = node.getAttribute('v-text')
this.__watchers[attr].push(new Watch(node, this, attr, 'innerHTML'))
}
}
}
}
class Watch {
constructor(el, vue, exp, att) {
this.el = el
this.vue = vue
this.exp = exp
this.att = att
// this.update();
}
update () {
console.log(this,'this.vue.$data[this.exp]',this.vue.$data[this.exp])
console.log(this.el[this.att],'1111444565445')
console.log(this.att,"this.attthis.attthis.att")
this.el[this.att] = this.vue.$data[this.exp]
}
}
const app = new Vue({
data () {
return {
name: '',
age: ''
}
}
})
console.log('vue对象:', app)
// 初始化vue对象的元素
app.mount('#app')