Skip to content

Instantly share code, notes, and snippets.

@delbertbeta
Created February 24, 2019 11:49
Show Gist options
  • Save delbertbeta/7530d70ccc28719815267417774ab309 to your computer and use it in GitHub Desktop.
Save delbertbeta/7530d70ccc28719815267417774ab309 to your computer and use it in GitHub Desktop.
Using proxy to implement limited Vue's computed function.
let obj = {
data: {
a: 0
},
computed: {
b: function () {
console.log('a changed! Now a is ', this.a)
return this.a + 1
}
}
}
let root = new Proxy(obj, {
get: (target, key) => {
if (key in target.data) {
return dataProxy[key]
} else if (key in target.computed) {
return values[key]
} else {
return undefined
}
},
set: (target, key, value) => {
if (key in target.data) {
dataProxy[key] = value
} else if (key in target.computed) {
throw Error('Can\'t do this!')
} else {
throw Error('Undefined key!')
}
}
})
let deps = {}
let tempDep = null
let dataProxy = new Proxy(obj.data, {
get: (target, key) => {
if (tempDep !== null) {
deps[key] = deps[key] ? deps[key] : new Set()
deps[key].add(tempDep)
}
return target[key]
},
set: (target, key, value) => {
Reflect.set(target, key, value)
if (deps[key]) {
for (let v of deps[key]) {
v()
}
}
}
})
let values = {}
for (let key in obj.computed) {
function dep() {
values[key] = obj.computed[key].call(root)
}
tempDep = dep
dep()
tempDep = null
}
console.log(root.a)
console.log(root.b)
root.a++
console.log(root.a)
console.log(root.b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment