SlideShare a Scribd company logo
1 of 35
Download to read offline
Reactivity in Vue 3
Marko Bošković
1
About me
Marko Bošković
Senior Frontend Developer @ Barrage
UX / Web Performace
2
What is reactivity?
So reactivity or reactive programming is a declarative
programming paradigm concerned with data streams and the
propagation of change.
3
4 . 1
4 . 2
Spreadsheets
5
6
detect changes in values of our variables
track the function that changes that values
trigger that function so it can update the final value
7
https://vuejs.org/v2/guide/reactivity.html
8
// data
const data = { x: 3, y: 6 };
// real data and deps behind
let realX = data.x;
let realY = data.y;
const realDepsX = [];
const realDepsY = [];
// track and trigger a property
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
const trackY = () => {
if (isDryRun && currentDep) {
realDepsY.push(currentDep);
}
};
const triggerY = () => {
realDepsY.forEach((dep) => dep());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
9
// data
const data = { x: 3, y: 6 };
// real data and deps behind
let realX = data.x;
let realY = data.y;
const realDepsX = [];
const realDepsY = [];
// track and trigger a property
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
const trackY = () => {
if (isDryRun && currentDep) {
realDepsY.push(currentDep);
}
};
const triggerY = () => {
realDepsY.forEach((dep) => dep());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const data = { x: 3, y: 6 };
// data1
2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
9
// data
const data = { x: 3, y: 6 };
// real data and deps behind
let realX = data.x;
let realY = data.y;
const realDepsX = [];
const realDepsY = [];
// track and trigger a property
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
const trackY = () => {
if (isDryRun && currentDep) {
realDepsY.push(currentDep);
}
};
const triggerY = () => {
realDepsY.forEach((dep) => dep());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const data = { x: 3, y: 6 };
// data1
2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
let realX = data.x;
let realY = data.y;
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
5
6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
9
// data
const data = { x: 3, y: 6 };
// real data and deps behind
let realX = data.x;
let realY = data.y;
const realDepsX = [];
const realDepsY = [];
// track and trigger a property
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
const trackY = () => {
if (isDryRun && currentDep) {
realDepsY.push(currentDep);
}
};
const triggerY = () => {
realDepsY.forEach((dep) => dep());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const data = { x: 3, y: 6 };
// data1
2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
let realX = data.x;
let realY = data.y;
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
5
6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const realDepsX = [];
const realDepsY = [];
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
7
8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
9
// data
const data = { x: 3, y: 6 };
// real data and deps behind
let realX = data.x;
let realY = data.y;
const realDepsX = [];
const realDepsY = [];
// track and trigger a property
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
const trackY = () => {
if (isDryRun && currentDep) {
realDepsY.push(currentDep);
}
};
const triggerY = () => {
realDepsY.forEach((dep) => dep());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const data = { x: 3, y: 6 };
// data1
2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
let realX = data.x;
let realY = data.y;
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
5
6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const realDepsX = [];
const realDepsY = [];
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
7
8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
11
12
13
14
15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
9
// data
const data = { x: 3, y: 6 };
// real data and deps behind
let realX = data.x;
let realY = data.y;
const realDepsX = [];
const realDepsY = [];
// track and trigger a property
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
const trackY = () => {
if (isDryRun && currentDep) {
realDepsY.push(currentDep);
}
};
const triggerY = () => {
realDepsY.forEach((dep) => dep());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const data = { x: 3, y: 6 };
// data1
2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
let realX = data.x;
let realY = data.y;
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
5
6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const realDepsX = [];
const realDepsY = [];
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
7
8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
11
12
13
14
15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
16
17
18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
};27
28
// make it reactive29
Object.defineProperty(data, "x", {30
9
// data
const data = { x: 3, y: 6 };
// real data and deps behind
let realX = data.x;
let realY = data.y;
const realDepsX = [];
const realDepsY = [];
// track and trigger a property
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
const trackY = () => {
if (isDryRun && currentDep) {
realDepsY.push(currentDep);
}
};
const triggerY = () => {
realDepsY.forEach((dep) => dep());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const data = { x: 3, y: 6 };
// data1
2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
let realX = data.x;
let realY = data.y;
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
5
6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const realDepsX = [];
const realDepsY = [];
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
7
8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
11
12
13
14
15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
16
17
18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
Object.defineProperty(data, "x", {
get() {
// track target func we are running
trackX();
return realX;
},
set(v) {
realX = v;
// rerun targeted functions
triggerX();
},
});
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
};27
28
// make it reactive29
30
31
32
33
34
35
36
37
38
39
40
41
Object.defineProperty(data, "y", {42
get() {43
trackY();44
return realY;45
},46
set(v) {47
realY = v;48
9
// data
const data = { x: 3, y: 6 };
// real data and deps behind
let realX = data.x;
let realY = data.y;
const realDepsX = [];
const realDepsY = [];
// track and trigger a property
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
const trackY = () => {
if (isDryRun && currentDep) {
realDepsY.push(currentDep);
}
};
const triggerY = () => {
realDepsY.forEach((dep) => dep());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const data = { x: 3, y: 6 };
// data1
2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
let realX = data.x;
let realY = data.y;
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
5
6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const realDepsX = [];
const realDepsY = [];
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
7
8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
11
12
13
14
15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
16
17
18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const watch = (fn) => {
isDryRun = true;
currentDep = fn;
fn();
currentDep = null;
isDryRun = false;
};
return realY;45
},46
set(v) {47
realY = v;48
triggerY();49
},50
});51
52
// watch a function53
let isDryRun = false;54
let currentDep = null;55
56
57
58
59
60
61
62
63
// define 3 functions64
const depA = () => console.log(`x = ${data.x}`);65
const depB = () => console.log(`y = ${data.y}`);66
const depC = () => console.log(`x + y = ${data.x + data.y}`);67
68
// dry-run all dependents69
watch(depA);70
watch(depB);71
9
// data
const data = { x: 3, y: 6 };
// real data and deps behind
let realX = data.x;
let realY = data.y;
const realDepsX = [];
const realDepsY = [];
// track and trigger a property
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
const trackY = () => {
if (isDryRun && currentDep) {
realDepsY.push(currentDep);
}
};
const triggerY = () => {
realDepsY.forEach((dep) => dep());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const data = { x: 3, y: 6 };
// data1
2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
let realX = data.x;
let realY = data.y;
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
5
6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const realDepsX = [];
const realDepsY = [];
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
7
8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
11
12
13
14
15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
16
17
18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const depA = () => console.log(`x = ${data.x}`);
const depB = () => console.log(`y = ${data.y}`);
const depC = () => console.log(`x + y = ${data.x + data.y}`);
52
// watch a function53
let isDryRun = false;54
let currentDep = null;55
const watch = (fn) => {56
isDryRun = true;57
currentDep = fn;58
fn();59
currentDep = null;60
isDryRun = false;61
};62
63
// define 3 functions64
65
66
67
68
// dry-run all dependents69
watch(depA);70
watch(depB);71
watch(depC);72
// output: x = 3, y = 6, x + y = 973
74
75
// mutate data76
data.x = 6;77
// 6 128
9
// data
const data = { x: 3, y: 6 };
// real data and deps behind
let realX = data.x;
let realY = data.y;
const realDepsX = [];
const realDepsY = [];
// track and trigger a property
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
const trackY = () => {
if (isDryRun && currentDep) {
realDepsY.push(currentDep);
}
};
const triggerY = () => {
realDepsY.forEach((dep) => dep());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const data = { x: 3, y: 6 };
// data1
2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
let realX = data.x;
let realY = data.y;
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
5
6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const realDepsX = [];
const realDepsY = [];
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
7
8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
11
12
13
14
15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
16
17
18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
watch(depA);
watch(depB);
watch(depC);
let currentDep = null;55
const watch = (fn) => {56
isDryRun = true;57
currentDep = fn;58
fn();59
currentDep = null;60
isDryRun = false;61
};62
63
// define 3 functions64
const depA = () => console.log(`x = ${data.x}`);65
const depB = () => console.log(`y = ${data.y}`);66
const depC = () => console.log(`x + y = ${data.x + data.y}`);67
68
// dry-run all dependents69
70
71
72
// output: x = 3, y = 6, x + y = 973
74
75
// mutate data76
data.x = 6;77
// output: x = 6, x + y = 1278
79
data.y = 9;80
9
// data
const data = { x: 3, y: 6 };
// real data and deps behind
let realX = data.x;
let realY = data.y;
const realDepsX = [];
const realDepsY = [];
// track and trigger a property
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
const trackY = () => {
if (isDryRun && currentDep) {
realDepsY.push(currentDep);
}
};
const triggerY = () => {
realDepsY.forEach((dep) => dep());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const data = { x: 3, y: 6 };
// data1
2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
let realX = data.x;
let realY = data.y;
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
5
6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const realDepsX = [];
const realDepsY = [];
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
7
8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const trackX = () => {
if (isDryRun && currentDep) {
realDepsX.push(currentDep);
}
};
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
11
12
13
14
15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
const triggerX = () => {
realDepsX.forEach((dep) => dep());
};
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
16
17
18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
// data1
const data = { x: 3, y: 6 };2
3
// real data and deps behind4
let realX = data.x;5
let realY = data.y;6
const realDepsX = [];7
const realDepsY = [];8
9
// track and trigger a property10
const trackX = () => {11
if (isDryRun && currentDep) {12
realDepsX.push(currentDep);13
}14
};15
const triggerX = () => {16
realDepsX.forEach((dep) => dep());17
};18
19
const trackY = () => {20
if (isDryRun && currentDep) {21
realDepsY.push(currentDep);22
}23
};24
const triggerY = () => {25
realDepsY.forEach((dep) => dep());26
}27
data.x = 6;
data.y = 9;
let currentDep = null;55
const watch = (fn) => {56
isDryRun = true;57
currentDep = fn;58
fn();59
currentDep = null;60
isDryRun = false;61
};62
63
// define 3 functions64
const depA = () => console.log(`x = ${data.x}`);65
const depB = () => console.log(`y = ${data.y}`);66
const depC = () => console.log(`x + y = ${data.x + data.y}`);67
68
// dry-run all dependents69
watch(depA);70
watch(depB);71
watch(depC);72
// output: x = 3, y = 6, x + y = 973
74
75
// mutate data76
77
// output: x = 6, x + y = 1278
79
80
9
Problems:
Setting array items by assigning value to a certain index. (e.g. arr[0] =
value)
Setting the length of an array. (e.g. arr.length = 0)
Adding a new property to an object. (e.g. obj.newKey = value) So it needs
some complementary APIs like Vue.$set(obj, newKey, value).
10
// data
const data = { x: 3, y: 6 };
// a Map to record dependets
const dependentMap = new Map()
// track and trigger a property
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
11
// data
const data = { x: 3, y: 6 };
// a Map to record dependets
const dependentMap = new Map()
// track and trigger a property
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const data = { x: 3, y: 6 };
const dependentMap = new Map()
// data1
2
3
// a Map to record dependets4
5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
11
// data
const data = { x: 3, y: 6 };
// a Map to record dependets
const dependentMap = new Map()
// track and trigger a property
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const data = { x: 3, y: 6 };
const dependentMap = new Map()
// data1
2
3
// a Map to record dependets4
5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
8
9
10
11
12
13
14
15
16
17
18
19
20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const proxy = new Proxy(data, {25
get(...args) {26
track("get", ...args);27
11
// data
const data = { x: 3, y: 6 };
// a Map to record dependets
const dependentMap = new Map()
// track and trigger a property
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const data = { x: 3, y: 6 };
const dependentMap = new Map()
// data1
2
3
// a Map to record dependets4
5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
8
9
10
11
12
13
14
15
16
17
18
19
20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
21
22
23
24
const proxy = new Proxy(data, {25
get(...args) {26
track("get", ...args);27
return Reflect.get(...args);28
},29
set(...args) {30
Reflect.set(...args);31
trigger("set", ...args);32
},33
});34
35
11
// data
const data = { x: 3, y: 6 };
// a Map to record dependets
const dependentMap = new Map()
// track and trigger a property
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const data = { x: 3, y: 6 };
const dependentMap = new Map()
// data1
2
3
// a Map to record dependets4
5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
8
9
10
11
12
13
14
15
16
17
18
19
20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
21
22
23
24
const proxy = new Proxy(data, {
get(...args) {
track("get", ...args);
return Reflect.get(...args);
},
set(...args) {
Reflect.set(...args);
trigger("set", ...args);
},
});
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
25
26
27
28
29
30
31
32
33
34
35
// watch functions36
const depA = () => console.log(`x = ${proxy.x}`)37
const depB = () => console.log(`y = ${proxy.y}`)38
const depC = () => console.log(`x + y = ${proxy.x + proxy.y}`)39
40
// watch41
let isDryRun = false42
11
// data
const data = { x: 3, y: 6 };
// a Map to record dependets
const dependentMap = new Map()
// track and trigger a property
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const data = { x: 3, y: 6 };
const dependentMap = new Map()
// data1
2
3
// a Map to record dependets4
5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
8
9
10
11
12
13
14
15
16
17
18
19
20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
21
22
23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
get(...args) {
track("get", ...args);
return Reflect.get(...args);
},
/ checking /14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const proxy = new Proxy(data, {25
26
27
28
29
set(...args) {30
Reflect.set(...args);31
trigger("set", ...args);32
},33
});34
35
// watch functions36
const depA = () => console.log(`x = ${proxy.x}`)37
const depB = () => console.log(`y = ${proxy.y}`)38
const depC = () => console.log(`x + y = ${proxy.x + proxy.y}`)39
40
11
// data
const data = { x: 3, y: 6 };
// a Map to record dependets
const dependentMap = new Map()
// track and trigger a property
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const data = { x: 3, y: 6 };
const dependentMap = new Map()
// data1
2
3
// a Map to record dependets4
5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
8
9
10
11
12
13
14
15
16
17
18
19
20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
21
22
23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
set(...args) {
Reflect.set(...args);
trigger("set", ...args);
},
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const proxy = new Proxy(data, {25
get(...args) {26
track("get", ...args);27
return Reflect.get(...args);28
},29
30
31
32
33
});34
35
// watch functions36
const depA = () => console.log(`x = ${proxy.x}`)37
const depB = () => console.log(`y = ${proxy.y}`)38
const depC = () => console.log(`x + y = ${proxy.x + proxy.y}`)39
40
// watch41
let isDryRun = false42
let currentFn = null43
const watch = fn => {44
11
// data
const data = { x: 3, y: 6 };
// a Map to record dependets
const dependentMap = new Map()
// track and trigger a property
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const data = { x: 3, y: 6 };
const dependentMap = new Map()
// data1
2
3
// a Map to record dependets4
5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
8
9
10
11
12
13
14
15
16
17
18
19
20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
21
22
23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const depA = () => console.log(`x = ${proxy.x}`)
const depB = () => console.log(`y = ${proxy.y}`)
const depC = () => console.log(`x + y = ${proxy.x + proxy.y}`)
const proxy = new Proxy(data, {25
get(...args) {26
track("get", ...args);27
return Reflect.get(...args);28
},29
set(...args) {30
Reflect.set(...args);31
trigger("set", ...args);32
},33
});34
35
// watch functions36
37
38
39
40
// watch41
let isDryRun = false42
let currentFn = null43
const watch = fn => {44
isDryRun = true45
currentFn = fn46
fn()47
currentFn = null48
isDryRun = false49
}50
51
11
// data
const data = { x: 3, y: 6 };
// a Map to record dependets
const dependentMap = new Map()
// track and trigger a property
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const data = { x: 3, y: 6 };
const dependentMap = new Map()
// data1
2
3
// a Map to record dependets4
5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
8
9
10
11
12
13
14
15
16
17
18
19
20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
21
22
23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const watch = fn => {
isDryRun = true
currentFn = fn
fn()
currentFn = null
isDryRun = false
}
});34
35
// watch functions36
const depA = () => console.log(`x = ${proxy.x}`)37
const depB = () => console.log(`y = ${proxy.y}`)38
const depC = () => console.log(`x + y = ${proxy.x + proxy.y}`)39
40
// watch41
let isDryRun = false42
let currentFn = null43
44
45
46
47
48
49
50
51
watch(depA);52
watch(depB);53
watch(depC);54
// output: x = 3, y = 6, x + y = 955
56
// mutate data57
proxy.x = 6;58
// output: x = 6, x + y = 1259
60
11
// data
const data = { x: 3, y: 6 };
// a Map to record dependets
const dependentMap = new Map()
// track and trigger a property
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const data = { x: 3, y: 6 };
const dependentMap = new Map()
// data1
2
3
// a Map to record dependets4
5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
8
9
10
11
12
13
14
15
16
17
18
19
20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
21
22
23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
watch(depA);
watch(depB);
watch(depC);
// output: x = 3, y = 6, x + y = 9
const depA = () => console.log(`x = ${proxy.x}`)37
const depB = () => console.log(`y = ${proxy.y}`)38
const depC = () => console.log(`x + y = ${proxy.x + proxy.y}`)39
40
// watch41
let isDryRun = false42
let currentFn = null43
const watch = fn => {44
isDryRun = true45
currentFn = fn46
fn()47
currentFn = null48
isDryRun = false49
}50
51
52
53
54
55
56
// mutate data57
proxy.x = 6;58
// output: x = 6, x + y = 1259
60
proxy.y = 9;61
// output: y = 9, x + y = 1562
11
// data
const data = { x: 3, y: 6 };
// a Map to record dependets
const dependentMap = new Map()
// track and trigger a property
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const data = { x: 3, y: 6 };
const dependentMap = new Map()
// data1
2
3
// a Map to record dependets4
5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const track = (type, data, propName) => {
if (isDryRun && currentFn) {
/* checking */
if (!dependentMap.has(data)) {
dependentMap.set(data, new Map())
}
/* checking */
if (!dependentMap.get(data).has(propName)) {
dependentMap.get(data).set(propName, new Set())
}
dependentMap.get(data).get(propName).add(currentFn)
}
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
8
9
10
11
12
13
14
15
16
17
18
19
20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
const trigger = (type, data, propName) => {
dependentMap.get(data).get(propName).forEach(fn => fn())
}
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
21
22
23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
// data1
const data = { x: 3, y: 6 };2
3
// a Map to record dependets4
const dependentMap = new Map()5
6
// track and trigger a property7
const track = (type, data, propName) => {8
if (isDryRun && currentFn) {9
/* checking */10
if (!dependentMap.has(data)) {11
dependentMap.set(data, new Map())12
}13
/* checking */14
if (!dependentMap.get(data).has(propName)) {15
dependentMap.get(data).set(propName, new Set())16
}17
dependentMap.get(data).get(propName).add(currentFn)18
}19
}20
const trigger = (type, data, propName) => {21
dependentMap.get(data).get(propName).forEach(fn => fn())22
}23
24
proxy.x = 6;
proxy.y = 9;
const depA = () => console.log(`x = ${proxy.x}`)37
const depB = () => console.log(`y = ${proxy.y}`)38
const depC = () => console.log(`x + y = ${proxy.x + proxy.y}`)39
40
// watch41
let isDryRun = false42
let currentFn = null43
const watch = fn => {44
isDryRun = true45
currentFn = fn46
fn()47
currentFn = null48
isDryRun = false49
}50
51
watch(depA);52
watch(depB);53
watch(depC);54
// output: x = 3, y = 6, x + y = 955
56
// mutate data57
58
// output: x = 6, x + y = 1259
60
61
// output: y = 9, x + y = 1562
11
Conclusion
- ES6 Proxy solution reactivity
- Reflect helps with better binding to `this`
- No more relying on `Object.defineProperty`
- Reactivity is abstracted from the component instance
12
Links
Vue reactivity in Depth
https://vuejs.org/v2/guide/reactivity.html
Understand Vue Reactivity Implementation Step by Step
https://medium.com/js-dojo/understand-vue-reactivity-implementation-step-by-step-
599c3d51cd6c
Vue 3
https://github.com/vuejs/vue-next
13
Visit our website
barrage.net
contact@barrage.net
Say Hello
@_aussieboi
Thank you
14

More Related Content

What's hot

Os lab file c programs
Os lab file c programsOs lab file c programs
Os lab file c programsKandarp Tiwari
 
D3 svg & angular
D3 svg & angularD3 svg & angular
D3 svg & angular500Tech
 
JavaScript Futures—ES2017 and Beyond
JavaScript Futures—ES2017 and BeyondJavaScript Futures—ES2017 and Beyond
JavaScript Futures—ES2017 and BeyondJeff Strauss
 
The Ring programming language version 1.5.4 book - Part 59 of 185
The Ring programming language version 1.5.4 book - Part 59 of 185The Ring programming language version 1.5.4 book - Part 59 of 185
The Ring programming language version 1.5.4 book - Part 59 of 185Mahmoud Samir Fayed
 
Solutionsfor co2 C Programs for data structures
Solutionsfor co2 C Programs for data structuresSolutionsfor co2 C Programs for data structures
Solutionsfor co2 C Programs for data structuresLakshmi Sarvani Videla
 
DAA Lab File C Programs
DAA Lab File C ProgramsDAA Lab File C Programs
DAA Lab File C ProgramsKandarp Tiwari
 
Михаил Матросов, Повседневный С++: boost и STL
Михаил Матросов, Повседневный С++: boost и STLМихаил Матросов, Повседневный С++: boost и STL
Михаил Матросов, Повседневный С++: boost и STLSergey Platonov
 
Cg my own programs
Cg my own programsCg my own programs
Cg my own programsAmit Kapoor
 
You will learn RxJS in 2017
You will learn RxJS in 2017You will learn RxJS in 2017
You will learn RxJS in 2017名辰 洪
 
Watch out: Observables are here to stay
Watch out: Observables are here to stayWatch out: Observables are here to stay
Watch out: Observables are here to stayGuilherme Ventura
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScriptMark
 
Dynamically Evolving Systems: Cluster Analysis Using Time
Dynamically Evolving Systems: Cluster Analysis Using TimeDynamically Evolving Systems: Cluster Analysis Using Time
Dynamically Evolving Systems: Cluster Analysis Using TimeMagnify Analytic Solutions
 
CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...
CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...
CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...CodiLime
 
Add Some Fun to Your Functional Programming With RXJS
Add Some Fun to Your Functional Programming With RXJSAdd Some Fun to Your Functional Programming With RXJS
Add Some Fun to Your Functional Programming With RXJSRyan Anklam
 
Binary Search Tree
Binary Search TreeBinary Search Tree
Binary Search Treeraviahuja11
 
RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術名辰 洪
 
The Ring programming language version 1.9 book - Part 78 of 210
The Ring programming language version 1.9 book - Part 78 of 210The Ring programming language version 1.9 book - Part 78 of 210
The Ring programming language version 1.9 book - Part 78 of 210Mahmoud Samir Fayed
 

What's hot (20)

Os lab file c programs
Os lab file c programsOs lab file c programs
Os lab file c programs
 
D3 svg & angular
D3 svg & angularD3 svg & angular
D3 svg & angular
 
JavaScript Futures—ES2017 and Beyond
JavaScript Futures—ES2017 and BeyondJavaScript Futures—ES2017 and Beyond
JavaScript Futures—ES2017 and Beyond
 
The Ring programming language version 1.5.4 book - Part 59 of 185
The Ring programming language version 1.5.4 book - Part 59 of 185The Ring programming language version 1.5.4 book - Part 59 of 185
The Ring programming language version 1.5.4 book - Part 59 of 185
 
Solutionsfor co2 C Programs for data structures
Solutionsfor co2 C Programs for data structuresSolutionsfor co2 C Programs for data structures
Solutionsfor co2 C Programs for data structures
 
DAA Lab File C Programs
DAA Lab File C ProgramsDAA Lab File C Programs
DAA Lab File C Programs
 
C programs
C programsC programs
C programs
 
Михаил Матросов, Повседневный С++: boost и STL
Михаил Матросов, Повседневный С++: boost и STLМихаил Матросов, Повседневный С++: boost и STL
Михаил Матросов, Повседневный С++: boost и STL
 
Cg my own programs
Cg my own programsCg my own programs
Cg my own programs
 
You will learn RxJS in 2017
You will learn RxJS in 2017You will learn RxJS in 2017
You will learn RxJS in 2017
 
Watch out: Observables are here to stay
Watch out: Observables are here to stayWatch out: Observables are here to stay
Watch out: Observables are here to stay
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
 
Dynamically Evolving Systems: Cluster Analysis Using Time
Dynamically Evolving Systems: Cluster Analysis Using TimeDynamically Evolving Systems: Cluster Analysis Using Time
Dynamically Evolving Systems: Cluster Analysis Using Time
 
CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...
CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...
CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...
 
662305 LAB13
662305 LAB13662305 LAB13
662305 LAB13
 
Add Some Fun to Your Functional Programming With RXJS
Add Some Fun to Your Functional Programming With RXJSAdd Some Fun to Your Functional Programming With RXJS
Add Some Fun to Your Functional Programming With RXJS
 
Binary Search Tree
Binary Search TreeBinary Search Tree
Binary Search Tree
 
Quantum neural network
Quantum neural networkQuantum neural network
Quantum neural network
 
RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術
 
The Ring programming language version 1.9 book - Part 78 of 210
The Ring programming language version 1.9 book - Part 78 of 210The Ring programming language version 1.9 book - Part 78 of 210
The Ring programming language version 1.9 book - Part 78 of 210
 

Similar to Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)

Reactive programming with RxJS - ByteConf 2018
Reactive programming with RxJS - ByteConf 2018Reactive programming with RxJS - ByteConf 2018
Reactive programming with RxJS - ByteConf 2018Tracy Lee
 
Using Arbor/ RGraph JS libaries for Data Visualisation
Using Arbor/ RGraph JS libaries for Data VisualisationUsing Arbor/ RGraph JS libaries for Data Visualisation
Using Arbor/ RGraph JS libaries for Data VisualisationAlex Hardman
 
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015NAVER / MusicPlatform
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Astrails
 
YQL and YUI - Javascript from server to user
YQL and YUI - Javascript from server to userYQL and YUI - Javascript from server to user
YQL and YUI - Javascript from server to userTom Croucher
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJSKyung Yeol Kim
 
All I know about rsc.io/c2go
All I know about rsc.io/c2goAll I know about rsc.io/c2go
All I know about rsc.io/c2goMoriyoshi Koizumi
 
Beyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS AppsBeyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS AppsRebecca Murphey
 
Write a program that reads a graph from a file and determines whether.docx
 Write a program that reads a graph from a file and determines whether.docx Write a program that reads a graph from a file and determines whether.docx
Write a program that reads a graph from a file and determines whether.docxajoy21
 
Javascript & Ajax Basics
Javascript & Ajax BasicsJavascript & Ajax Basics
Javascript & Ajax BasicsRichard Paul
 
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...GeeksLab Odessa
 
DoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdf
DoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdfDoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdf
DoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdfaathiauto
 
Critical buckling load geometric nonlinearity analysis of springs with rigid ...
Critical buckling load geometric nonlinearity analysis of springs with rigid ...Critical buckling load geometric nonlinearity analysis of springs with rigid ...
Critical buckling load geometric nonlinearity analysis of springs with rigid ...Salar Delavar Qashqai
 
Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016Codemotion
 

Similar to Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage) (20)

Reactive programming with RxJS - ByteConf 2018
Reactive programming with RxJS - ByteConf 2018Reactive programming with RxJS - ByteConf 2018
Reactive programming with RxJS - ByteConf 2018
 
Using Arbor/ RGraph JS libaries for Data Visualisation
Using Arbor/ RGraph JS libaries for Data VisualisationUsing Arbor/ RGraph JS libaries for Data Visualisation
Using Arbor/ RGraph JS libaries for Data Visualisation
 
JQuery Flot
JQuery FlotJQuery Flot
JQuery Flot
 
Snow
SnowSnow
Snow
 
Snow
SnowSnow
Snow
 
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.
 
YQL and YUI - Javascript from server to user
YQL and YUI - Javascript from server to userYQL and YUI - Javascript from server to user
YQL and YUI - Javascript from server to user
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJS
 
All I know about rsc.io/c2go
All I know about rsc.io/c2goAll I know about rsc.io/c2go
All I know about rsc.io/c2go
 
Beyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS AppsBeyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS Apps
 
Write a program that reads a graph from a file and determines whether.docx
 Write a program that reads a graph from a file and determines whether.docx Write a program that reads a graph from a file and determines whether.docx
Write a program that reads a graph from a file and determines whether.docx
 
Myraytracer
MyraytracerMyraytracer
Myraytracer
 
Javascript & Ajax Basics
Javascript & Ajax BasicsJavascript & Ajax Basics
Javascript & Ajax Basics
 
YQL Tutorial
YQL TutorialYQL Tutorial
YQL Tutorial
 
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
 
DoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdf
DoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdfDoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdf
DoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdf
 
DataStructures notes
DataStructures notesDataStructures notes
DataStructures notes
 
Critical buckling load geometric nonlinearity analysis of springs with rigid ...
Critical buckling load geometric nonlinearity analysis of springs with rigid ...Critical buckling load geometric nonlinearity analysis of springs with rigid ...
Critical buckling load geometric nonlinearity analysis of springs with rigid ...
 
Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016
 

More from Shift Conference

Shift Remote: AI: How Does Face Recognition Work (ars futura)
Shift Remote: AI: How Does Face Recognition Work  (ars futura)Shift Remote: AI: How Does Face Recognition Work  (ars futura)
Shift Remote: AI: How Does Face Recognition Work (ars futura)Shift Conference
 
Shift Remote: AI: Behind the scenes development in an AI company - Matija Ili...
Shift Remote: AI: Behind the scenes development in an AI company - Matija Ili...Shift Remote: AI: Behind the scenes development in an AI company - Matija Ili...
Shift Remote: AI: Behind the scenes development in an AI company - Matija Ili...Shift Conference
 
Shift Remote: AI: Smarter AI with analytical graph databases - Victor Lee (Ti...
Shift Remote: AI: Smarter AI with analytical graph databases - Victor Lee (Ti...Shift Remote: AI: Smarter AI with analytical graph databases - Victor Lee (Ti...
Shift Remote: AI: Smarter AI with analytical graph databases - Victor Lee (Ti...Shift Conference
 
Shift Remote: DevOps: Devops with Azure Devops and Github - Juarez Junior (Mi...
Shift Remote: DevOps: Devops with Azure Devops and Github - Juarez Junior (Mi...Shift Remote: DevOps: Devops with Azure Devops and Github - Juarez Junior (Mi...
Shift Remote: DevOps: Devops with Azure Devops and Github - Juarez Junior (Mi...Shift Conference
 
Shift Remote: DevOps: Autodesks research into digital twins for AEC - Kean W...
Shift Remote: DevOps: Autodesks research into digital twins for AEC -  Kean W...Shift Remote: DevOps: Autodesks research into digital twins for AEC -  Kean W...
Shift Remote: DevOps: Autodesks research into digital twins for AEC - Kean W...Shift Conference
 
Shift Remote: DevOps: When metrics are not enough, and everyone is on-call - ...
Shift Remote: DevOps: When metrics are not enough, and everyone is on-call - ...Shift Remote: DevOps: When metrics are not enough, and everyone is on-call - ...
Shift Remote: DevOps: When metrics are not enough, and everyone is on-call - ...Shift Conference
 
Shift Remote: DevOps: Modern incident management with opsgenie - Kristijan L...
Shift Remote: DevOps: Modern incident management with opsgenie -  Kristijan L...Shift Remote: DevOps: Modern incident management with opsgenie -  Kristijan L...
Shift Remote: DevOps: Modern incident management with opsgenie - Kristijan L...Shift Conference
 
Shift Remote: DevOps: Gitlab ci hands-on experience - Ivan Rimac (Barrage)
Shift Remote: DevOps: Gitlab ci hands-on experience - Ivan Rimac (Barrage)Shift Remote: DevOps: Gitlab ci hands-on experience - Ivan Rimac (Barrage)
Shift Remote: DevOps: Gitlab ci hands-on experience - Ivan Rimac (Barrage)Shift Conference
 
Shift Remote: DevOps: DevOps Heroes - Adding Advanced Automation to your Tool...
Shift Remote: DevOps: DevOps Heroes - Adding Advanced Automation to your Tool...Shift Remote: DevOps: DevOps Heroes - Adding Advanced Automation to your Tool...
Shift Remote: DevOps: DevOps Heroes - Adding Advanced Automation to your Tool...Shift Conference
 
Shift Remote: DevOps: An (Un)expected Journey - Zeljko Margeta (RBA)
Shift Remote: DevOps: An (Un)expected Journey - Zeljko Margeta (RBA)Shift Remote: DevOps: An (Un)expected Journey - Zeljko Margeta (RBA)
Shift Remote: DevOps: An (Un)expected Journey - Zeljko Margeta (RBA)Shift Conference
 
Shift Remote: Game Dev - Localising Mobile Games - Marta Kunic (Nanobit)
Shift Remote: Game Dev - Localising Mobile Games - Marta Kunic (Nanobit)Shift Remote: Game Dev - Localising Mobile Games - Marta Kunic (Nanobit)
Shift Remote: Game Dev - Localising Mobile Games - Marta Kunic (Nanobit)Shift Conference
 
Shift Remote: Game Dev - Challenges Introducing Open Source to the Games Indu...
Shift Remote: Game Dev - Challenges Introducing Open Source to the Games Indu...Shift Remote: Game Dev - Challenges Introducing Open Source to the Games Indu...
Shift Remote: Game Dev - Challenges Introducing Open Source to the Games Indu...Shift Conference
 
Shift Remote: Game Dev - Ghost in the Machine: Authorial Voice in System Desi...
Shift Remote: Game Dev - Ghost in the Machine: Authorial Voice in System Desi...Shift Remote: Game Dev - Ghost in the Machine: Authorial Voice in System Desi...
Shift Remote: Game Dev - Ghost in the Machine: Authorial Voice in System Desi...Shift Conference
 
Shift Remote: Game Dev - Building Better Worlds with Game Culturalization - K...
Shift Remote: Game Dev - Building Better Worlds with Game Culturalization - K...Shift Remote: Game Dev - Building Better Worlds with Game Culturalization - K...
Shift Remote: Game Dev - Building Better Worlds with Game Culturalization - K...Shift Conference
 
Shift Remote: Game Dev - Open Match: An Open Source Matchmaking Framework - J...
Shift Remote: Game Dev - Open Match: An Open Source Matchmaking Framework - J...Shift Remote: Game Dev - Open Match: An Open Source Matchmaking Framework - J...
Shift Remote: Game Dev - Open Match: An Open Source Matchmaking Framework - J...Shift Conference
 
Shift Remote: Game Dev - Designing Inside the Box - Fernando Reyes Medina (34...
Shift Remote: Game Dev - Designing Inside the Box - Fernando Reyes Medina (34...Shift Remote: Game Dev - Designing Inside the Box - Fernando Reyes Medina (34...
Shift Remote: Game Dev - Designing Inside the Box - Fernando Reyes Medina (34...Shift Conference
 
Shift Remote: Mobile - Efficiently Building Native Frameworks for Multiple Pl...
Shift Remote: Mobile - Efficiently Building Native Frameworks for Multiple Pl...Shift Remote: Mobile - Efficiently Building Native Frameworks for Multiple Pl...
Shift Remote: Mobile - Efficiently Building Native Frameworks for Multiple Pl...Shift Conference
 
Shift Remote: Mobile - Introduction to MotionLayout on Android - Denis Fodor ...
Shift Remote: Mobile - Introduction to MotionLayout on Android - Denis Fodor ...Shift Remote: Mobile - Introduction to MotionLayout on Android - Denis Fodor ...
Shift Remote: Mobile - Introduction to MotionLayout on Android - Denis Fodor ...Shift Conference
 
Shift Remote: Mobile - Devops-ify your life with Github Actions - Nicola Cort...
Shift Remote: Mobile - Devops-ify your life with Github Actions - Nicola Cort...Shift Remote: Mobile - Devops-ify your life with Github Actions - Nicola Cort...
Shift Remote: Mobile - Devops-ify your life with Github Actions - Nicola Cort...Shift Conference
 
Shift Remote: WEB - GraphQL and React – Quick Start - Dubravko Bogovic (Infobip)
Shift Remote: WEB - GraphQL and React – Quick Start - Dubravko Bogovic (Infobip)Shift Remote: WEB - GraphQL and React – Quick Start - Dubravko Bogovic (Infobip)
Shift Remote: WEB - GraphQL and React – Quick Start - Dubravko Bogovic (Infobip)Shift Conference
 

More from Shift Conference (20)

Shift Remote: AI: How Does Face Recognition Work (ars futura)
Shift Remote: AI: How Does Face Recognition Work  (ars futura)Shift Remote: AI: How Does Face Recognition Work  (ars futura)
Shift Remote: AI: How Does Face Recognition Work (ars futura)
 
Shift Remote: AI: Behind the scenes development in an AI company - Matija Ili...
Shift Remote: AI: Behind the scenes development in an AI company - Matija Ili...Shift Remote: AI: Behind the scenes development in an AI company - Matija Ili...
Shift Remote: AI: Behind the scenes development in an AI company - Matija Ili...
 
Shift Remote: AI: Smarter AI with analytical graph databases - Victor Lee (Ti...
Shift Remote: AI: Smarter AI with analytical graph databases - Victor Lee (Ti...Shift Remote: AI: Smarter AI with analytical graph databases - Victor Lee (Ti...
Shift Remote: AI: Smarter AI with analytical graph databases - Victor Lee (Ti...
 
Shift Remote: DevOps: Devops with Azure Devops and Github - Juarez Junior (Mi...
Shift Remote: DevOps: Devops with Azure Devops and Github - Juarez Junior (Mi...Shift Remote: DevOps: Devops with Azure Devops and Github - Juarez Junior (Mi...
Shift Remote: DevOps: Devops with Azure Devops and Github - Juarez Junior (Mi...
 
Shift Remote: DevOps: Autodesks research into digital twins for AEC - Kean W...
Shift Remote: DevOps: Autodesks research into digital twins for AEC -  Kean W...Shift Remote: DevOps: Autodesks research into digital twins for AEC -  Kean W...
Shift Remote: DevOps: Autodesks research into digital twins for AEC - Kean W...
 
Shift Remote: DevOps: When metrics are not enough, and everyone is on-call - ...
Shift Remote: DevOps: When metrics are not enough, and everyone is on-call - ...Shift Remote: DevOps: When metrics are not enough, and everyone is on-call - ...
Shift Remote: DevOps: When metrics are not enough, and everyone is on-call - ...
 
Shift Remote: DevOps: Modern incident management with opsgenie - Kristijan L...
Shift Remote: DevOps: Modern incident management with opsgenie -  Kristijan L...Shift Remote: DevOps: Modern incident management with opsgenie -  Kristijan L...
Shift Remote: DevOps: Modern incident management with opsgenie - Kristijan L...
 
Shift Remote: DevOps: Gitlab ci hands-on experience - Ivan Rimac (Barrage)
Shift Remote: DevOps: Gitlab ci hands-on experience - Ivan Rimac (Barrage)Shift Remote: DevOps: Gitlab ci hands-on experience - Ivan Rimac (Barrage)
Shift Remote: DevOps: Gitlab ci hands-on experience - Ivan Rimac (Barrage)
 
Shift Remote: DevOps: DevOps Heroes - Adding Advanced Automation to your Tool...
Shift Remote: DevOps: DevOps Heroes - Adding Advanced Automation to your Tool...Shift Remote: DevOps: DevOps Heroes - Adding Advanced Automation to your Tool...
Shift Remote: DevOps: DevOps Heroes - Adding Advanced Automation to your Tool...
 
Shift Remote: DevOps: An (Un)expected Journey - Zeljko Margeta (RBA)
Shift Remote: DevOps: An (Un)expected Journey - Zeljko Margeta (RBA)Shift Remote: DevOps: An (Un)expected Journey - Zeljko Margeta (RBA)
Shift Remote: DevOps: An (Un)expected Journey - Zeljko Margeta (RBA)
 
Shift Remote: Game Dev - Localising Mobile Games - Marta Kunic (Nanobit)
Shift Remote: Game Dev - Localising Mobile Games - Marta Kunic (Nanobit)Shift Remote: Game Dev - Localising Mobile Games - Marta Kunic (Nanobit)
Shift Remote: Game Dev - Localising Mobile Games - Marta Kunic (Nanobit)
 
Shift Remote: Game Dev - Challenges Introducing Open Source to the Games Indu...
Shift Remote: Game Dev - Challenges Introducing Open Source to the Games Indu...Shift Remote: Game Dev - Challenges Introducing Open Source to the Games Indu...
Shift Remote: Game Dev - Challenges Introducing Open Source to the Games Indu...
 
Shift Remote: Game Dev - Ghost in the Machine: Authorial Voice in System Desi...
Shift Remote: Game Dev - Ghost in the Machine: Authorial Voice in System Desi...Shift Remote: Game Dev - Ghost in the Machine: Authorial Voice in System Desi...
Shift Remote: Game Dev - Ghost in the Machine: Authorial Voice in System Desi...
 
Shift Remote: Game Dev - Building Better Worlds with Game Culturalization - K...
Shift Remote: Game Dev - Building Better Worlds with Game Culturalization - K...Shift Remote: Game Dev - Building Better Worlds with Game Culturalization - K...
Shift Remote: Game Dev - Building Better Worlds with Game Culturalization - K...
 
Shift Remote: Game Dev - Open Match: An Open Source Matchmaking Framework - J...
Shift Remote: Game Dev - Open Match: An Open Source Matchmaking Framework - J...Shift Remote: Game Dev - Open Match: An Open Source Matchmaking Framework - J...
Shift Remote: Game Dev - Open Match: An Open Source Matchmaking Framework - J...
 
Shift Remote: Game Dev - Designing Inside the Box - Fernando Reyes Medina (34...
Shift Remote: Game Dev - Designing Inside the Box - Fernando Reyes Medina (34...Shift Remote: Game Dev - Designing Inside the Box - Fernando Reyes Medina (34...
Shift Remote: Game Dev - Designing Inside the Box - Fernando Reyes Medina (34...
 
Shift Remote: Mobile - Efficiently Building Native Frameworks for Multiple Pl...
Shift Remote: Mobile - Efficiently Building Native Frameworks for Multiple Pl...Shift Remote: Mobile - Efficiently Building Native Frameworks for Multiple Pl...
Shift Remote: Mobile - Efficiently Building Native Frameworks for Multiple Pl...
 
Shift Remote: Mobile - Introduction to MotionLayout on Android - Denis Fodor ...
Shift Remote: Mobile - Introduction to MotionLayout on Android - Denis Fodor ...Shift Remote: Mobile - Introduction to MotionLayout on Android - Denis Fodor ...
Shift Remote: Mobile - Introduction to MotionLayout on Android - Denis Fodor ...
 
Shift Remote: Mobile - Devops-ify your life with Github Actions - Nicola Cort...
Shift Remote: Mobile - Devops-ify your life with Github Actions - Nicola Cort...Shift Remote: Mobile - Devops-ify your life with Github Actions - Nicola Cort...
Shift Remote: Mobile - Devops-ify your life with Github Actions - Nicola Cort...
 
Shift Remote: WEB - GraphQL and React – Quick Start - Dubravko Bogovic (Infobip)
Shift Remote: WEB - GraphQL and React – Quick Start - Dubravko Bogovic (Infobip)Shift Remote: WEB - GraphQL and React – Quick Start - Dubravko Bogovic (Infobip)
Shift Remote: WEB - GraphQL and React – Quick Start - Dubravko Bogovic (Infobip)
 

Recently uploaded

10.pdfMature Call girls in Dubai +971563133746 Dubai Call girls
10.pdfMature Call girls in Dubai +971563133746 Dubai Call girls10.pdfMature Call girls in Dubai +971563133746 Dubai Call girls
10.pdfMature Call girls in Dubai +971563133746 Dubai Call girlsstephieert
 
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Dana Luther
 
How is AI changing journalism? (v. April 2024)
How is AI changing journalism? (v. April 2024)How is AI changing journalism? (v. April 2024)
How is AI changing journalism? (v. April 2024)Damian Radcliffe
 
Call Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on Delivery
Call Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on DeliveryCall Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on Delivery
Call Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on Deliverybabeytanya
 
Russian Call girls in Dubai +971563133746 Dubai Call girls
Russian  Call girls in Dubai +971563133746 Dubai  Call girlsRussian  Call girls in Dubai +971563133746 Dubai  Call girls
Russian Call girls in Dubai +971563133746 Dubai Call girlsstephieert
 
Complet Documnetation for Smart Assistant Application for Disabled Person
Complet Documnetation   for Smart Assistant Application for Disabled PersonComplet Documnetation   for Smart Assistant Application for Disabled Person
Complet Documnetation for Smart Assistant Application for Disabled Personfurqan222004
 
Git and Github workshop GDSC MLRITM
Git and Github  workshop GDSC MLRITMGit and Github  workshop GDSC MLRITM
Git and Github workshop GDSC MLRITMgdsc13
 
Russian Call Girls in Kolkata Samaira 🤌 8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Samaira 🤌  8250192130 🚀 Vip Call Girls KolkataRussian Call Girls in Kolkata Samaira 🤌  8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Samaira 🤌 8250192130 🚀 Vip Call Girls Kolkataanamikaraghav4
 
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607dollysharma2066
 
VIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call Girl
VIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call GirlVIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call Girl
VIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call Girladitipandeya
 
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一Fs
 
AlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with FlowsAlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with FlowsThierry TROUIN ☁
 
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Gram Darshan PPT cyber rural in villages of india
Gram Darshan PPT cyber rural  in villages of indiaGram Darshan PPT cyber rural  in villages of india
Gram Darshan PPT cyber rural in villages of indiaimessage0108
 
VIP Kolkata Call Girl Salt Lake 👉 8250192130 Available With Room
VIP Kolkata Call Girl Salt Lake 👉 8250192130  Available With RoomVIP Kolkata Call Girl Salt Lake 👉 8250192130  Available With Room
VIP Kolkata Call Girl Salt Lake 👉 8250192130 Available With Roomishabajaj13
 
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一Fs
 
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Lucknow
 

Recently uploaded (20)

10.pdfMature Call girls in Dubai +971563133746 Dubai Call girls
10.pdfMature Call girls in Dubai +971563133746 Dubai Call girls10.pdfMature Call girls in Dubai +971563133746 Dubai Call girls
10.pdfMature Call girls in Dubai +971563133746 Dubai Call girls
 
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
 
How is AI changing journalism? (v. April 2024)
How is AI changing journalism? (v. April 2024)How is AI changing journalism? (v. April 2024)
How is AI changing journalism? (v. April 2024)
 
Call Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on Delivery
Call Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on DeliveryCall Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on Delivery
Call Girls In Mumbai Central Mumbai ❤️ 9920874524 👈 Cash on Delivery
 
Russian Call girls in Dubai +971563133746 Dubai Call girls
Russian  Call girls in Dubai +971563133746 Dubai  Call girlsRussian  Call girls in Dubai +971563133746 Dubai  Call girls
Russian Call girls in Dubai +971563133746 Dubai Call girls
 
Complet Documnetation for Smart Assistant Application for Disabled Person
Complet Documnetation   for Smart Assistant Application for Disabled PersonComplet Documnetation   for Smart Assistant Application for Disabled Person
Complet Documnetation for Smart Assistant Application for Disabled Person
 
Git and Github workshop GDSC MLRITM
Git and Github  workshop GDSC MLRITMGit and Github  workshop GDSC MLRITM
Git and Github workshop GDSC MLRITM
 
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Serviceyoung call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
 
Russian Call Girls in Kolkata Samaira 🤌 8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Samaira 🤌  8250192130 🚀 Vip Call Girls KolkataRussian Call Girls in Kolkata Samaira 🤌  8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Samaira 🤌 8250192130 🚀 Vip Call Girls Kolkata
 
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607
 
VIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call Girl
VIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call GirlVIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call Girl
VIP 7001035870 Find & Meet Hyderabad Call Girls LB Nagar high-profile Call Girl
 
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
 
AlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with FlowsAlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with Flows
 
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
 
Gram Darshan PPT cyber rural in villages of india
Gram Darshan PPT cyber rural  in villages of indiaGram Darshan PPT cyber rural  in villages of india
Gram Darshan PPT cyber rural in villages of india
 
VIP Kolkata Call Girl Salt Lake 👉 8250192130 Available With Room
VIP Kolkata Call Girl Salt Lake 👉 8250192130  Available With RoomVIP Kolkata Call Girl Salt Lake 👉 8250192130  Available With Room
VIP Kolkata Call Girl Salt Lake 👉 8250192130 Available With Room
 
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一
定制(Management毕业证书)新加坡管理大学毕业证成绩单原版一比一
 
Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
 
Call Girls Service Dwarka @9999965857 Delhi 🫦 No Advance VVIP 🍎 SERVICE
Call Girls Service Dwarka @9999965857 Delhi 🫦 No Advance  VVIP 🍎 SERVICECall Girls Service Dwarka @9999965857 Delhi 🫦 No Advance  VVIP 🍎 SERVICE
Call Girls Service Dwarka @9999965857 Delhi 🫦 No Advance VVIP 🍎 SERVICE
 
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
 

Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)

  • 1. Reactivity in Vue 3 Marko Bošković 1
  • 2. About me Marko Bošković Senior Frontend Developer @ Barrage UX / Web Performace 2
  • 3. What is reactivity? So reactivity or reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change. 3
  • 7. 6
  • 8. detect changes in values of our variables track the function that changes that values trigger that function so it can update the final value 7
  • 10. // data const data = { x: 3, y: 6 }; // real data and deps behind let realX = data.x; let realY = data.y; const realDepsX = []; const realDepsY = []; // track and trigger a property const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; const triggerX = () => { realDepsX.forEach((dep) => dep()); }; const trackY = () => { if (isDryRun && currentDep) { realDepsY.push(currentDep); } }; const triggerY = () => { realDepsY.forEach((dep) => dep()); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 9
  • 11. // data const data = { x: 3, y: 6 }; // real data and deps behind let realX = data.x; let realY = data.y; const realDepsX = []; const realDepsY = []; // track and trigger a property const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; const triggerX = () => { realDepsX.forEach((dep) => dep()); }; const trackY = () => { if (isDryRun && currentDep) { realDepsY.push(currentDep); } }; const triggerY = () => { realDepsY.forEach((dep) => dep()); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const data = { x: 3, y: 6 }; // data1 2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 9
  • 12. // data const data = { x: 3, y: 6 }; // real data and deps behind let realX = data.x; let realY = data.y; const realDepsX = []; const realDepsY = []; // track and trigger a property const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; const triggerX = () => { realDepsX.forEach((dep) => dep()); }; const trackY = () => { if (isDryRun && currentDep) { realDepsY.push(currentDep); } }; const triggerY = () => { realDepsY.forEach((dep) => dep()); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const data = { x: 3, y: 6 }; // data1 2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 let realX = data.x; let realY = data.y; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 5 6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 9
  • 13. // data const data = { x: 3, y: 6 }; // real data and deps behind let realX = data.x; let realY = data.y; const realDepsX = []; const realDepsY = []; // track and trigger a property const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; const triggerX = () => { realDepsX.forEach((dep) => dep()); }; const trackY = () => { if (isDryRun && currentDep) { realDepsY.push(currentDep); } }; const triggerY = () => { realDepsY.forEach((dep) => dep()); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const data = { x: 3, y: 6 }; // data1 2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 let realX = data.x; let realY = data.y; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 5 6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const realDepsX = []; const realDepsY = []; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 7 8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 9
  • 14. // data const data = { x: 3, y: 6 }; // real data and deps behind let realX = data.x; let realY = data.y; const realDepsX = []; const realDepsY = []; // track and trigger a property const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; const triggerX = () => { realDepsX.forEach((dep) => dep()); }; const trackY = () => { if (isDryRun && currentDep) { realDepsY.push(currentDep); } }; const triggerY = () => { realDepsY.forEach((dep) => dep()); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const data = { x: 3, y: 6 }; // data1 2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 let realX = data.x; let realY = data.y; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 5 6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const realDepsX = []; const realDepsY = []; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 7 8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 11 12 13 14 15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 9
  • 15. // data const data = { x: 3, y: 6 }; // real data and deps behind let realX = data.x; let realY = data.y; const realDepsX = []; const realDepsY = []; // track and trigger a property const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; const triggerX = () => { realDepsX.forEach((dep) => dep()); }; const trackY = () => { if (isDryRun && currentDep) { realDepsY.push(currentDep); } }; const triggerY = () => { realDepsY.forEach((dep) => dep()); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const data = { x: 3, y: 6 }; // data1 2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 let realX = data.x; let realY = data.y; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 5 6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const realDepsX = []; const realDepsY = []; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 7 8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 11 12 13 14 15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const triggerX = () => { realDepsX.forEach((dep) => dep()); }; // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 16 17 18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 };27 28 // make it reactive29 Object.defineProperty(data, "x", {30 9
  • 16. // data const data = { x: 3, y: 6 }; // real data and deps behind let realX = data.x; let realY = data.y; const realDepsX = []; const realDepsY = []; // track and trigger a property const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; const triggerX = () => { realDepsX.forEach((dep) => dep()); }; const trackY = () => { if (isDryRun && currentDep) { realDepsY.push(currentDep); } }; const triggerY = () => { realDepsY.forEach((dep) => dep()); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const data = { x: 3, y: 6 }; // data1 2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 let realX = data.x; let realY = data.y; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 5 6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const realDepsX = []; const realDepsY = []; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 7 8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 11 12 13 14 15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const triggerX = () => { realDepsX.forEach((dep) => dep()); }; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 16 17 18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 Object.defineProperty(data, "x", { get() { // track target func we are running trackX(); return realX; }, set(v) { realX = v; // rerun targeted functions triggerX(); }, }); realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 };27 28 // make it reactive29 30 31 32 33 34 35 36 37 38 39 40 41 Object.defineProperty(data, "y", {42 get() {43 trackY();44 return realY;45 },46 set(v) {47 realY = v;48 9
  • 17. // data const data = { x: 3, y: 6 }; // real data and deps behind let realX = data.x; let realY = data.y; const realDepsX = []; const realDepsY = []; // track and trigger a property const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; const triggerX = () => { realDepsX.forEach((dep) => dep()); }; const trackY = () => { if (isDryRun && currentDep) { realDepsY.push(currentDep); } }; const triggerY = () => { realDepsY.forEach((dep) => dep()); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const data = { x: 3, y: 6 }; // data1 2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 let realX = data.x; let realY = data.y; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 5 6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const realDepsX = []; const realDepsY = []; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 7 8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 11 12 13 14 15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const triggerX = () => { realDepsX.forEach((dep) => dep()); }; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 16 17 18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const watch = (fn) => { isDryRun = true; currentDep = fn; fn(); currentDep = null; isDryRun = false; }; return realY;45 },46 set(v) {47 realY = v;48 triggerY();49 },50 });51 52 // watch a function53 let isDryRun = false;54 let currentDep = null;55 56 57 58 59 60 61 62 63 // define 3 functions64 const depA = () => console.log(`x = ${data.x}`);65 const depB = () => console.log(`y = ${data.y}`);66 const depC = () => console.log(`x + y = ${data.x + data.y}`);67 68 // dry-run all dependents69 watch(depA);70 watch(depB);71 9
  • 18. // data const data = { x: 3, y: 6 }; // real data and deps behind let realX = data.x; let realY = data.y; const realDepsX = []; const realDepsY = []; // track and trigger a property const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; const triggerX = () => { realDepsX.forEach((dep) => dep()); }; const trackY = () => { if (isDryRun && currentDep) { realDepsY.push(currentDep); } }; const triggerY = () => { realDepsY.forEach((dep) => dep()); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const data = { x: 3, y: 6 }; // data1 2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 let realX = data.x; let realY = data.y; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 5 6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const realDepsX = []; const realDepsY = []; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 7 8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 11 12 13 14 15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const triggerX = () => { realDepsX.forEach((dep) => dep()); }; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 16 17 18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const depA = () => console.log(`x = ${data.x}`); const depB = () => console.log(`y = ${data.y}`); const depC = () => console.log(`x + y = ${data.x + data.y}`); 52 // watch a function53 let isDryRun = false;54 let currentDep = null;55 const watch = (fn) => {56 isDryRun = true;57 currentDep = fn;58 fn();59 currentDep = null;60 isDryRun = false;61 };62 63 // define 3 functions64 65 66 67 68 // dry-run all dependents69 watch(depA);70 watch(depB);71 watch(depC);72 // output: x = 3, y = 6, x + y = 973 74 75 // mutate data76 data.x = 6;77 // 6 128 9
  • 19. // data const data = { x: 3, y: 6 }; // real data and deps behind let realX = data.x; let realY = data.y; const realDepsX = []; const realDepsY = []; // track and trigger a property const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; const triggerX = () => { realDepsX.forEach((dep) => dep()); }; const trackY = () => { if (isDryRun && currentDep) { realDepsY.push(currentDep); } }; const triggerY = () => { realDepsY.forEach((dep) => dep()); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const data = { x: 3, y: 6 }; // data1 2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 let realX = data.x; let realY = data.y; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 5 6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const realDepsX = []; const realDepsY = []; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 7 8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 11 12 13 14 15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const triggerX = () => { realDepsX.forEach((dep) => dep()); }; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 16 17 18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 watch(depA); watch(depB); watch(depC); let currentDep = null;55 const watch = (fn) => {56 isDryRun = true;57 currentDep = fn;58 fn();59 currentDep = null;60 isDryRun = false;61 };62 63 // define 3 functions64 const depA = () => console.log(`x = ${data.x}`);65 const depB = () => console.log(`y = ${data.y}`);66 const depC = () => console.log(`x + y = ${data.x + data.y}`);67 68 // dry-run all dependents69 70 71 72 // output: x = 3, y = 6, x + y = 973 74 75 // mutate data76 data.x = 6;77 // output: x = 6, x + y = 1278 79 data.y = 9;80 9
  • 20. // data const data = { x: 3, y: 6 }; // real data and deps behind let realX = data.x; let realY = data.y; const realDepsX = []; const realDepsY = []; // track and trigger a property const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; const triggerX = () => { realDepsX.forEach((dep) => dep()); }; const trackY = () => { if (isDryRun && currentDep) { realDepsY.push(currentDep); } }; const triggerY = () => { realDepsY.forEach((dep) => dep()); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const data = { x: 3, y: 6 }; // data1 2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 let realX = data.x; let realY = data.y; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 5 6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const realDepsX = []; const realDepsY = []; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 7 8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const trackX = () => { if (isDryRun && currentDep) { realDepsX.push(currentDep); } }; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 11 12 13 14 15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 const triggerX = () => { realDepsX.forEach((dep) => dep()); }; // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 16 17 18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 // data1 const data = { x: 3, y: 6 };2 3 // real data and deps behind4 let realX = data.x;5 let realY = data.y;6 const realDepsX = [];7 const realDepsY = [];8 9 // track and trigger a property10 const trackX = () => {11 if (isDryRun && currentDep) {12 realDepsX.push(currentDep);13 }14 };15 const triggerX = () => {16 realDepsX.forEach((dep) => dep());17 };18 19 const trackY = () => {20 if (isDryRun && currentDep) {21 realDepsY.push(currentDep);22 }23 };24 const triggerY = () => {25 realDepsY.forEach((dep) => dep());26 }27 data.x = 6; data.y = 9; let currentDep = null;55 const watch = (fn) => {56 isDryRun = true;57 currentDep = fn;58 fn();59 currentDep = null;60 isDryRun = false;61 };62 63 // define 3 functions64 const depA = () => console.log(`x = ${data.x}`);65 const depB = () => console.log(`y = ${data.y}`);66 const depC = () => console.log(`x + y = ${data.x + data.y}`);67 68 // dry-run all dependents69 watch(depA);70 watch(depB);71 watch(depC);72 // output: x = 3, y = 6, x + y = 973 74 75 // mutate data76 77 // output: x = 6, x + y = 1278 79 80 9
  • 21. Problems: Setting array items by assigning value to a certain index. (e.g. arr[0] = value) Setting the length of an array. (e.g. arr.length = 0) Adding a new property to an object. (e.g. obj.newKey = value) So it needs some complementary APIs like Vue.$set(obj, newKey, value). 10
  • 22. // data const data = { x: 3, y: 6 }; // a Map to record dependets const dependentMap = new Map() // track and trigger a property const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 11
  • 23. // data const data = { x: 3, y: 6 }; // a Map to record dependets const dependentMap = new Map() // track and trigger a property const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const data = { x: 3, y: 6 }; const dependentMap = new Map() // data1 2 3 // a Map to record dependets4 5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 11
  • 24. // data const data = { x: 3, y: 6 }; // a Map to record dependets const dependentMap = new Map() // track and trigger a property const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const data = { x: 3, y: 6 }; const dependentMap = new Map() // data1 2 3 // a Map to record dependets4 5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 8 9 10 11 12 13 14 15 16 17 18 19 20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const proxy = new Proxy(data, {25 get(...args) {26 track("get", ...args);27 11
  • 25. // data const data = { x: 3, y: 6 }; // a Map to record dependets const dependentMap = new Map() // track and trigger a property const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const data = { x: 3, y: 6 }; const dependentMap = new Map() // data1 2 3 // a Map to record dependets4 5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 8 9 10 11 12 13 14 15 16 17 18 19 20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 21 22 23 24 const proxy = new Proxy(data, {25 get(...args) {26 track("get", ...args);27 return Reflect.get(...args);28 },29 set(...args) {30 Reflect.set(...args);31 trigger("set", ...args);32 },33 });34 35 11
  • 26. // data const data = { x: 3, y: 6 }; // a Map to record dependets const dependentMap = new Map() // track and trigger a property const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const data = { x: 3, y: 6 }; const dependentMap = new Map() // data1 2 3 // a Map to record dependets4 5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 8 9 10 11 12 13 14 15 16 17 18 19 20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 21 22 23 24 const proxy = new Proxy(data, { get(...args) { track("get", ...args); return Reflect.get(...args); }, set(...args) { Reflect.set(...args); trigger("set", ...args); }, }); dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 25 26 27 28 29 30 31 32 33 34 35 // watch functions36 const depA = () => console.log(`x = ${proxy.x}`)37 const depB = () => console.log(`y = ${proxy.y}`)38 const depC = () => console.log(`x + y = ${proxy.x + proxy.y}`)39 40 // watch41 let isDryRun = false42 11
  • 27. // data const data = { x: 3, y: 6 }; // a Map to record dependets const dependentMap = new Map() // track and trigger a property const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const data = { x: 3, y: 6 }; const dependentMap = new Map() // data1 2 3 // a Map to record dependets4 5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 8 9 10 11 12 13 14 15 16 17 18 19 20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 21 22 23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 get(...args) { track("get", ...args); return Reflect.get(...args); }, / checking /14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const proxy = new Proxy(data, {25 26 27 28 29 set(...args) {30 Reflect.set(...args);31 trigger("set", ...args);32 },33 });34 35 // watch functions36 const depA = () => console.log(`x = ${proxy.x}`)37 const depB = () => console.log(`y = ${proxy.y}`)38 const depC = () => console.log(`x + y = ${proxy.x + proxy.y}`)39 40 11
  • 28. // data const data = { x: 3, y: 6 }; // a Map to record dependets const dependentMap = new Map() // track and trigger a property const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const data = { x: 3, y: 6 }; const dependentMap = new Map() // data1 2 3 // a Map to record dependets4 5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 8 9 10 11 12 13 14 15 16 17 18 19 20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 21 22 23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 set(...args) { Reflect.set(...args); trigger("set", ...args); }, dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const proxy = new Proxy(data, {25 get(...args) {26 track("get", ...args);27 return Reflect.get(...args);28 },29 30 31 32 33 });34 35 // watch functions36 const depA = () => console.log(`x = ${proxy.x}`)37 const depB = () => console.log(`y = ${proxy.y}`)38 const depC = () => console.log(`x + y = ${proxy.x + proxy.y}`)39 40 // watch41 let isDryRun = false42 let currentFn = null43 const watch = fn => {44 11
  • 29. // data const data = { x: 3, y: 6 }; // a Map to record dependets const dependentMap = new Map() // track and trigger a property const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const data = { x: 3, y: 6 }; const dependentMap = new Map() // data1 2 3 // a Map to record dependets4 5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 8 9 10 11 12 13 14 15 16 17 18 19 20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 21 22 23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const depA = () => console.log(`x = ${proxy.x}`) const depB = () => console.log(`y = ${proxy.y}`) const depC = () => console.log(`x + y = ${proxy.x + proxy.y}`) const proxy = new Proxy(data, {25 get(...args) {26 track("get", ...args);27 return Reflect.get(...args);28 },29 set(...args) {30 Reflect.set(...args);31 trigger("set", ...args);32 },33 });34 35 // watch functions36 37 38 39 40 // watch41 let isDryRun = false42 let currentFn = null43 const watch = fn => {44 isDryRun = true45 currentFn = fn46 fn()47 currentFn = null48 isDryRun = false49 }50 51 11
  • 30. // data const data = { x: 3, y: 6 }; // a Map to record dependets const dependentMap = new Map() // track and trigger a property const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const data = { x: 3, y: 6 }; const dependentMap = new Map() // data1 2 3 // a Map to record dependets4 5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 8 9 10 11 12 13 14 15 16 17 18 19 20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 21 22 23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const watch = fn => { isDryRun = true currentFn = fn fn() currentFn = null isDryRun = false } });34 35 // watch functions36 const depA = () => console.log(`x = ${proxy.x}`)37 const depB = () => console.log(`y = ${proxy.y}`)38 const depC = () => console.log(`x + y = ${proxy.x + proxy.y}`)39 40 // watch41 let isDryRun = false42 let currentFn = null43 44 45 46 47 48 49 50 51 watch(depA);52 watch(depB);53 watch(depC);54 // output: x = 3, y = 6, x + y = 955 56 // mutate data57 proxy.x = 6;58 // output: x = 6, x + y = 1259 60 11
  • 31. // data const data = { x: 3, y: 6 }; // a Map to record dependets const dependentMap = new Map() // track and trigger a property const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const data = { x: 3, y: 6 }; const dependentMap = new Map() // data1 2 3 // a Map to record dependets4 5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 8 9 10 11 12 13 14 15 16 17 18 19 20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 21 22 23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 watch(depA); watch(depB); watch(depC); // output: x = 3, y = 6, x + y = 9 const depA = () => console.log(`x = ${proxy.x}`)37 const depB = () => console.log(`y = ${proxy.y}`)38 const depC = () => console.log(`x + y = ${proxy.x + proxy.y}`)39 40 // watch41 let isDryRun = false42 let currentFn = null43 const watch = fn => {44 isDryRun = true45 currentFn = fn46 fn()47 currentFn = null48 isDryRun = false49 }50 51 52 53 54 55 56 // mutate data57 proxy.x = 6;58 // output: x = 6, x + y = 1259 60 proxy.y = 9;61 // output: y = 9, x + y = 1562 11
  • 32. // data const data = { x: 3, y: 6 }; // a Map to record dependets const dependentMap = new Map() // track and trigger a property const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const data = { x: 3, y: 6 }; const dependentMap = new Map() // data1 2 3 // a Map to record dependets4 5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const track = (type, data, propName) => { if (isDryRun && currentFn) { /* checking */ if (!dependentMap.has(data)) { dependentMap.set(data, new Map()) } /* checking */ if (!dependentMap.get(data).has(propName)) { dependentMap.get(data).set(propName, new Set()) } dependentMap.get(data).get(propName).add(currentFn) } } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 8 9 10 11 12 13 14 15 16 17 18 19 20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 const trigger = (type, data, propName) => { dependentMap.get(data).get(propName).forEach(fn => fn()) } // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 21 22 23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 // data1 const data = { x: 3, y: 6 };2 3 // a Map to record dependets4 const dependentMap = new Map()5 6 // track and trigger a property7 const track = (type, data, propName) => {8 if (isDryRun && currentFn) {9 /* checking */10 if (!dependentMap.has(data)) {11 dependentMap.set(data, new Map())12 }13 /* checking */14 if (!dependentMap.get(data).has(propName)) {15 dependentMap.get(data).set(propName, new Set())16 }17 dependentMap.get(data).get(propName).add(currentFn)18 }19 }20 const trigger = (type, data, propName) => {21 dependentMap.get(data).get(propName).forEach(fn => fn())22 }23 24 proxy.x = 6; proxy.y = 9; const depA = () => console.log(`x = ${proxy.x}`)37 const depB = () => console.log(`y = ${proxy.y}`)38 const depC = () => console.log(`x + y = ${proxy.x + proxy.y}`)39 40 // watch41 let isDryRun = false42 let currentFn = null43 const watch = fn => {44 isDryRun = true45 currentFn = fn46 fn()47 currentFn = null48 isDryRun = false49 }50 51 watch(depA);52 watch(depB);53 watch(depC);54 // output: x = 3, y = 6, x + y = 955 56 // mutate data57 58 // output: x = 6, x + y = 1259 60 61 // output: y = 9, x + y = 1562 11
  • 33. Conclusion - ES6 Proxy solution reactivity - Reflect helps with better binding to `this` - No more relying on `Object.defineProperty` - Reactivity is abstracted from the component instance 12
  • 34. Links Vue reactivity in Depth https://vuejs.org/v2/guide/reactivity.html Understand Vue Reactivity Implementation Step by Step https://medium.com/js-dojo/understand-vue-reactivity-implementation-step-by-step- 599c3d51cd6c Vue 3 https://github.com/vuejs/vue-next 13