q
q copied to clipboard
Using the Proxy - Challenge from your blog
Hello @zserge 👋🏽 I recently stumbled upon and enjoyed reading your blog post on making this tiny version of Vue! It's a great exercise in conciseness.
At the end of your blog post, you mention if anyone would like to try to write a version of the program by using the javascript proxy object they could try and open a PR. After a bit of trying I came up with:
const proxy = q => {
const deps = {}
return new Proxy(q, {
get(target, p) {
if ($dep) {
if (!(p in deps))
deps[p] = []
deps[p].push($dep)
}
return Reflect.get(...arguments)
},
set(target, p, value) {
const success = Reflect.set(...arguments)
if (!p.startsWith('$') && success) {
for (const dep of deps[p]){
dep(value)
}
}
return success
}
})
Which works, but unfortunately it returns a new object instead of mutating the given one. I could not figure out how to get around this, if you know how - I love to know. Instead, it's the client's responsibility to wrap the proxy before like:
let model = {name: 'John'};
model = proxy(model)
Q(el, model)
model.name = 'Jane' // this works
Which is lame LOL. I was wondering how Vue3
got around this problem but turns out they don't solve this problem! The new app constructor is just a function called createApp
and if you change the data element afterwards, the page is not updated... (ex.)
let model = {data() : { return {name: "john"} } } // you have to use functions for data now
createApp(model).mount('#app');
model.data = () => {return {name:"jane"}} // Doesn't update the dom
So maybe the proxy approach would require a more thorough change. Maybe even a Q3
branch? Lol.
Anyways that's what I wanted to share. Cheers!