Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VueJs make computed property reactive

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:

  1. 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

  2. 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?

like image 957
Emma Avatar asked Sep 02 '25 02:09

Emma


2 Answers

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).

like image 152
Moisés Hiraldo Avatar answered Sep 04 '25 21:09

Moisés Hiraldo


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.

like image 36
v-moe Avatar answered Sep 04 '25 21:09

v-moe