Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 69 additions & 2 deletions 2019/Aug/Week4/reactive-variables.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,75 @@
/**
* 响应式变量
*/
module.exports = class ReactiveVariables {
constructor(variables) {
class Dep {
constructor () {
this.deps = [];
}

depend () {
if (Dep.target && this.deps.indexOf(Dep.target) === -1) {
this.deps.push(Dep.target);
}
}

notify () {
this.deps.forEach((dep) => {
dep();
})
}
}

class Observable {
constructor (obj) {
Object.keys(obj).forEach((key) => {
Observable.defineReactive(obj, key, obj[key])
});
return obj;
}

static defineReactive (obj, key, val) {
const dep = new Dep();
Object.defineProperty(obj, key, {
get () {
dep.depend();
return val;
},
set (newVal) {
val = newVal;
dep.notify();
}
})
}
}

class Watcher {
constructor (obj, key, cb) {
this.cb = () => {
obj[key] = cb.bind(obj).call();
};
Dep.target = this.cb;
this.cb();
Dep.target = null;
}
}

module.exports = class ReactiveVariables {
constructor(variables) {
const attrs = {};
const funcs = {};
Object.keys(variables).forEach((key) => {
const variable = variables[key];
if(typeof variables[key] === 'function' ){
funcs[key] = variable;
}else{
attrs[key] = variable;
}
});
this.obj = new Observable(attrs);
Object.keys(funcs).forEach((key) => {
// eslint-disable-next-line
new Watcher(this.obj, key, funcs[key]);
});
return this.obj;
}
};