Skip to content

Instantly share code, notes, and snippets.

@mathieutu
Created April 6, 2021 21:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mathieutu/c138770bf8c9c7ad2de1fb5d3458d31b to your computer and use it in GitHub Desktop.
Save mathieutu/c138770bf8c9c7ad2de1fb5d3458d31b to your computer and use it in GitHub Desktop.
Simple vuejs 3 like reactivity poc.
const reactiveMap = new WeakMap()
const targetMap = new WeakMap()
let activeEffect
const track = (target, key) => {
if (!activeEffect) return
let depsMap = targetMap.get(target)
if(!depsMap) {
targetMap.set(target, depsMap = new Map())
}
let deps = depsMap.get(key)
if(!deps) depsMap.set(key, deps = new Set())
deps.add(activeEffect)
}
const trigger = (target, key) => {
const deps = targetMap.get(target)
if(!deps) return
deps.get(key).forEach(effect => effect())
}
const reactive = (obj) => {
const existingProxy = reactiveMap.get(obj)
if (existingProxy) return existingProxy
const proxy = new Proxy(obj, {
get(target, key) {
track(target, key)
return target[key]
},
set(target, key, value) {
target[key] = value
trigger(target, key)
return true
}
})
reactiveMap.set(obj, proxy)
return proxy
}
const watchEffect = (effectFn) => {
activeEffect = effectFn
activeEffect()
activeEffect = null
}
const foo = reactive({ foo: 'bar' })
const computed = (fn) => {
return {
get value() {
track(this, 'value')
return fn()
}
}
}
const computedPlop = computed(() => foo.foo + 'bar')
watchEffect(() => {
console.log('foo changed', foo.foo)
})
watchEffect(() => {
console.log('plop changed', computedPlop.value)
})
foo.foo = 'baz'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment