1 class MVVM {
2 constructor(options) {
3 this.$options = options;
4 this.$el = options.el;
5 this.$data = options.data;
6 this.observe(this.$data);
7 new Compile(this);
8 }
9 observe(data) {
10 if (!data || typeof data !== 'object') {
11 return;
12 }
13 Object.keys(data).forEach(key => {
14 this.defineReactive(data, key, data[key]);
15 })
16 }
17 defineReactive(data, key, value) {
18 let dep = new Dep();
19 Object.defineProperty(data, key, {
20 configurable: false,
21 enumerable: true,
22 get: () => {
23 Dep.target && dep.add(Dep.target);
24 return value;
25 },
26 set: (newVal) => {
27 if (newVal === value) { return; }
28 value = newVal;
29 dep.notify();
30 }
31 })
32 }
33 }
34 class Dep {
35 constructor() {
36 this.deps = [];
37 }
38 add(dep) {
39 this.deps.push(dep);
40 }
41 notify() {
42 this.deps.forEach(dep => {
43 dep.update();
44 })
45 }
46 }
47 class Watcher {
48 constructor(vm, cb) {
49 this.vm = vm;
50 this.cb = cb;
51 Dep.target = this;
52 this.vm.$data['word'];
53 Dep.target = null;
54 }
55 update() {
56 this.cb.call(this.vm, this.vm.$data['word']);
57 }
58 }
59 class Compile {
60 constructor(vm) {
61 this.vm = vm;
62 this.changeInputValue(vm);
63 }
64 changeInputValue(vm) {
65 let inputs = document.querySelectorAll('input');
66 Array.from(inputs).forEach(input => {
67 this.update(input,vm);
68 input.addEventListener('input', (e) => {
69 vm.$data['word'] = e.target.value;
70 }, false)
71 })
72 }
73 update(input,vm) {
74 input.value = vm.$data['word'];
75 new Watcher(vm, function (value) {
76 input.value = value;
77 })
78 }
79 }