day190-MyVue-完善Complier、Watcher

要点

  1. 提取模板中的变量
  2. 完善WatcherObserver之间的桥梁,Dep中添加target

Complier

import Watcher from "./Watcher";

const REG = /\{\{(.*)\}\}/ // 取胡须括号中的内容
class Complier {
constructor(el, vm) {
this.el = document.querySelector(el) // 高效的原生DOM选择器,用着方便(比getElementsBy系列)
this.vm = vm
this.frag = this._createFragment()
this.el.appendChild(this.frag) // 整个element添加到这里,最后会清空
}
_createFragment () {
var frag = document.createDocumentFragment() // 文档碎片节点,比createElement多次添加到document.body效率高
var child
while(child = this.el.firstChild) {
this._compile(child) // 接收每个node的子节点
frag.appendChild(child) // 编译完之后,添加到碎片;appendChild做移动步骤;
}
return frag
}
_compile(node) {
if (node.nodeType === 1) { // 元素

}
if (node.nodeType === 3) { // 文本节点
if (REG.test(node.nodeValue)) {
var name = RegExp.$1 // 拿到第一个大括号里的
name = name.trim() // 得到属性名字
new Watcher(node, name, this.vm) // 观察得到的值
}
}
}
}

export default Complier

Watcher

import Dep from "./Dep";

/**
* 订阅的人附到Dep
*/
class Watcher {
constructor (node, name, vm) {
this.node = node
this.name = name
this.vm = vm
Dep.target = this // 注入,给Observer提供this,否则Observer不会主动注入listen(Dep.target)
this.update()
Dep.target = null
}
update () {
this.node.nodeValue = this.vm[this.name]
}

}

export default Watcher

Dep

添加target

/**
* 发布订阅事件
*/
class Dep {
// static target = null // 可能不被识别
constructor () {
this.listenerList = []
}
/**
* subs 传入Watcher,知道谁在监听
* @param {*} subs
*/
sub (subs) {
this.listenerList.push(subs)
}
notify () {
for (var i = 0; i < this.listenerList.length; i++) {
this.listenerList[i].update()
}
}
}
Dep.prototype.target = null // 兼容性

export default Dep
文章作者: lmislm
文章链接: http://lmislm.com/2019/07/22/2019-07-22/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LMISLMのBlog