I have a VueJS component like this
const MyComponent = Vue.extend({
props: ["myHandle"],
computed: {
name: {
get: function() { return myHandle.getName() },
set: function(newName) { myHandle.setName(newName) },
}
}
})
The problem is that setting the computed property name
does not trigger VueJs to update the property. Meaning the old name is what gets displayed on re-render.
Now, I'm fairly new to VueJS and i can see how this might be code smell, but the thing is that the myHandle
property is actually a handle to access data in a WebAssembly module written in rust. The rust code is where most of my state/model/source of truth lives.
The two unsatisfactory solutions i have found thus far are:
Use a method to retrieve the name instead of a computed property. Basically add a getName
method to my component and change my template code from <p> Your name is {{ name }}</p>
to <p> Your name is {{ getName() }}</p>
. Which will cause VueJs to not cache. In the future I'm planing to do expensive computations meaning unnecessary performance cost
Copy state from the rust side to my component. This I do not want to do since I would get multiple source of truth.
So is there some way to:
A: Get VueJS to understand that myHandle.setName
is a mutating method that should cause name
computed property to be updated.
B: Manually trigger an update.
C Solve it in some other manner?
Computed properties are cached based on their dependencies (data, props and other computed properties). If I've understood correctly, your computed property won't be reactive cause the only dependency is myHandle, and I assume that will never change. Look at it this way, Vue can only check that getName is returning a different value by actually calling the method, so there's nothing to cache.
If the name can only be changed from your Vue component, you can set it as a data field and add a watcher to update the WebAssembly value. Otherwise, if the name can be changed from non-Vue sources and you must call the getName method from the handler every time, you will have to come up with your own mechanism (maybe using a debounce function to limit the number of calls).
I don't know how your implementation of setName() is, but if it is
setName(newName) { this.name = newName; }
you might have run into the problem described here: https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
I would like to add that it is probably not a good idea to mutate myHandle as a prop, so I suggest that if you can refactor your code to use myHandle as a data property, to do so.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With