- function defineReactive(data, key, val) {
- observe(val); // 递归遍历所有子属性
- var dep = new Dep();
- Object.defineProperty(data, key, {
- enumerable: true,
- configurable: true,
- get: function() {
- if (是否需要添加订阅者) {
- dep.addSub(watcher); // 在这里添加一个订阅者
- }
- return val;
- },
- set: function(newVal) {
- if (val === newVal) {
- return;
- }
- val = newVal;
- console.log('属性' + key + '已经被监听了, 现在值为:"' + newVal.toString() + '"');
- dep.notify(); // 如果数据变化, 通知所有订阅者
- }
- });
- }
- function Dep () {
- this.subs = [];
- }
- Dep.prototype = {
- addSub: function(sub) {
- this.subs.push(sub);
- },
- notify: function() {
- this.subs.forEach(function(sub) {
- sub.update();
- });
- }
- };
实现 watcher
- function Watcher(vm, exp, cb) { // vm 为当前 dom 实例, exp 为指令绑定的动态数据或 {{}} 里的动态数据, cb 为更新函数
- this.cb = cb;
- this.vm = vm;
- this.exp = exp;
- this.value = this.get(); // 将自己添加到订阅器的操作
- }
- Watcher.prototype = {
- update: function() {
- this.run();
- },
- run: function() {
- var value = this.vm.data[this.exp];
- var oldVal = this.value;
- if (value !== oldVal) {
- this.value = value;
- this.cb.call(this.vm, value, oldVal);
- }
- },
- get: function() {
- Dep.target = this; // 缓存自己
- var value = this.vm.data[this.exp] // 强制执行监听器里的 get 函数
- Dep.target = null; // 释放自己
- return value;
- }
- };
实现 compile
作用:
1 解析模板指令, 并替换模板数据, 初始化视图;
2 将模板指令对应的节点绑定对应的更新函数, 初始化相应的订阅器;
首先需要解析的 dom 节点存入 fragment 片段里再进行处理:
- function compileElement (el) {
- var childNodes = el.childNodes;
- var self = this;
- [].slice.call(childNodes).forEach(function(node) {
- var reg = /\{\{(.*)\}\}/;
- var text = node.textContent;
- if (self.isTextNode(node) && reg.test(text)) { // 判断是否是符合这种形式 {{}} 的指令
- self.compileText(node, reg.exec(text)[1]);
- }
- if (node.childNodes && node.childNodes.length) {
- self.compileElement(node); // 继续递归遍历子节点
- }
- });
- },
- function compileText (node, exp) {
- var self = this;
- var initText = this.vm[exp];
- this.updateText(node, initText); // 将初始化的数据初始化到视图中
- new Watcher(this.vm, exp, function (value) { // 生成订阅器并绑定更新函数
- self.updateText(node, value);
- });
- },
- function (node, value) {
- node.textContent = typeof value == 'undefined' ? '' : value;
- }
来源: http://www.bubuko.com/infodetail-3527250.html