<script>
//发布者
class Vue {
constructor(options) {
this.options = options
this.$data = options.data
this.$el = document.querySelector(options.el)
this._directives = {} //存放订阅了对应数据的(什么东西)
//{myText:[订阅者1,订阅者2],mybox:[订阅者1]}
this.Observer(this.$data)
this.Compile(this.$el)
}
//劫持数据
Observer(data) {
//更新视图
for (let key in data) {
this._directives[key] = []
let _this = this._directives[key]
let val = data[key] //当前值
Object.defineProperty(this.$data, key, {
get: function () {
return val
},
set: function (newVal) {
if (newVal !== val) {
val = newVal
//[订阅者1,订阅者2]
_this.forEach(watch => {
watch.update()
});
}
}
})
}
}
//解析指令
Compile(el) {
let nodes = el.children //获取根节点下的子元素
for (let i = 0; i < nodes.length; i++) {
let node = nodes[i] //当前元素
if (node.children.length) {//如果还有子节点
this.Compile(node)
}
if (node.hasAttribute("v-text")) { //查找v-text
let attrVal = node.getAttribute("v-text")
this._directives[attrVal].push(new Watch(node, attrVal, this, 'innerHTML'))
}
if (node.hasAttribute("v-model")) { //查找vmodel
let attrVal = node.getAttribute("v-model")
this._directives[attrVal].push(new Watch(node, attrVal, this, 'value'))
let _this = this
node.addEventListener("input", (function () {
return function () {
//更新视图到模型
_this.$data[attrVal] = node.value
}
})())
}
}
}
}
//订阅者
class Watch {
constructor(el, vm, mySelf, attr) {
this.el = el
this.vm = vm
this.mySelf = mySelf
this.attr = attr
this.update()
}
update() {
this.el[this.attr] = this.mySelf.$data[this.vm]
//div对象[innerHTML]=vue对象.data["myText"]
}
}
</script>
<body>
<div id="app">
<h1>数据响应式</h1>
<div>
<div v-text="myText"></div>
<input type="text" v-model="myText">
</div>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
myText: '大吉大利,今晚吃鸡'
}
})
</script>
网友评论