Skip to content

Commit d497a3f

Browse files
committed
Added 7 and 8
1 parent 4b91938 commit d497a3f

File tree

3 files changed

+923
-0
lines changed

3 files changed

+923
-0
lines changed

07-computed.js

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
const targetMap = new WeakMap() // targetMap stores the effects that each object should re-run when it's updated
2+
let activeEffect = null // The active effect running
3+
4+
function track(target, key) {
5+
if (activeEffect) {
6+
// <------ Check to see if we have an activeEffect
7+
// We need to make sure this effect is being tracked.
8+
let depsMap = targetMap.get(target) // Get the current depsMap for this target
9+
if (!depsMap) {
10+
// There is no map.
11+
targetMap.set(target, (depsMap = new Map())) // Create one
12+
}
13+
let dep = depsMap.get(key) // Get the current dependencies (effects) that need to be run when this is set
14+
if (!dep) {
15+
// There is no dependencies (effects)
16+
depsMap.set(key, (dep = new Set())) // Create a new Set
17+
}
18+
dep.add(activeEffect) // Add effect to dependency map
19+
}
20+
}
21+
22+
function trigger(target, key) {
23+
const depsMap = targetMap.get(target) // Does this object have any properties that have dependencies (effects)
24+
if (!depsMap) {
25+
return
26+
}
27+
let dep = depsMap.get(key) // If there are dependencies (effects) associated with this
28+
if (dep) {
29+
dep.forEach(eff => {
30+
// run them all
31+
eff()
32+
})
33+
}
34+
}
35+
36+
function reactive(target) {
37+
const handler = {
38+
get(target, key, receiver) {
39+
let result = Reflect.get(target, key, receiver)
40+
track(target, key) // If this reactive property (target) is GET inside then track the effect to rerun on SET
41+
return result
42+
},
43+
set(target, key, value, receiver) {
44+
let oldValue = target[key]
45+
let result = Reflect.set(target, key, value, receiver)
46+
if (oldValue != result) {
47+
trigger(target, key) // If this reactive property (target) has effects to rerun on SET, trigger them.
48+
}
49+
return result
50+
},
51+
}
52+
return new Proxy(target, handler)
53+
}
54+
55+
function ref(raw) {
56+
const r = {
57+
get value() {
58+
track(r, 'value')
59+
return raw
60+
},
61+
set value(newVal) {
62+
raw = newVal
63+
trigger(r, 'value')
64+
},
65+
}
66+
return r
67+
}
68+
69+
function effect(eff) {
70+
activeEffect = eff
71+
activeEffect()
72+
activeEffect = null
73+
}
74+
75+
function computed(getter) {
76+
let result = ref()
77+
78+
effect(() => (result.value = getter()))
79+
80+
return result
81+
}
82+
83+
let product = reactive({ price: 5, quantity: 2 })
84+
85+
let salePrice = computed(() => {
86+
return product.price * 0.9
87+
})
88+
89+
let total = computed(() => {
90+
return salePrice.value * product.quantity
91+
})
92+
93+
console.log(
94+
`Before updated quantity total (should be 9) = ${total.value} salePrice (should be 4.5) = ${salePrice.value}`
95+
)
96+
product.quantity = 3
97+
console.log(
98+
`After updated quantity total (should be 13.5) = ${total.value} salePrice (should be 4.5) = ${salePrice.value}`
99+
)
100+
product.price = 10
101+
console.log(
102+
`After updated price total (should be 27) = ${total.value} salePrice (should be 9) = ${salePrice.value}`
103+
)
104+
105+
// Plus let's verify we can add additional objects to the reactive object
106+
107+
product.name = 'Shoes'
108+
109+
effect(() => {
110+
console.log(`Product name is now ${product.name}`)
111+
})
112+
113+
product.name = 'Socks'

08-vue-reactivity.js

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
var { reactive, computed, effect } = require('./reactivity.cjs')
2+
3+
let product = reactive({ price: 5, quantity: 2 })
4+
5+
let salePrice = computed(() => {
6+
return product.price * 0.9
7+
})
8+
9+
let total = computed(() => {
10+
return salePrice.value * product.quantity
11+
})
12+
13+
console.log(
14+
`Before updated quantity total (should be 9) = ${total.value} salePrice (should be 4.5) = ${salePrice.value}`
15+
)
16+
product.quantity = 3
17+
console.log(
18+
`After updated quantity total (should be 13.5) = ${total.value} salePrice (should be 4.5) = ${salePrice.value}`
19+
)
20+
product.price = 10
21+
console.log(
22+
`After updated price total (should be 27) = ${total.value} salePrice (should be 9) = ${salePrice.value}`
23+
)
24+
25+
product.name = 'Shoes'
26+
27+
effect(() => {
28+
console.log(`Product name is now ${product.name}`)
29+
})
30+
31+
product.name = 'Socks'

0 commit comments

Comments
 (0)