nitrovatter
nitrovatter

Reputation: 1211

Vue 3 - Make the specific class properties reactive

Is there any possibility to make some properties of the class instance reactive?

In the MobX it's fairly easy to do:

class Doubler {
    constructor(value) {
        makeObservable(this, {
            value: observable,
            double: computed,
        })
        this.value = value
    }

    get double() {
        return this.value * 2
    }
}

But it looks like impossible to do it in Vue.

1.The most closest result that I get is the following result:

class Doubler {
    constructor(value) {
        this.value = ref(value)
        this.double = computed(() => this.value.value * 2) // Ugly
    }
}

The computed code is ugly and it's using also differs:

const doubler = new Doubler(1)
double.value = 2 // No way!
double.value.value = 2 // That's it! Ugly, but that's it.

2.I can pass the created object to reactive function, but it make all properties reactive and it doesn't affect the internal implementation and it still will be ugly.

Is there any way to reproduce MobX approach in Vue?

Upvotes: 2

Views: 4021

Answers (1)

Lucas
Lucas

Reputation: 502

I don't think you can achieve it with classes. With objects though, the closest thing I can think of is something like this:

function createDoubler(value) {
  const doubler = reactive({ value })
  doubler.double = computed(() => state.value * 2)
  return doubler
}

const doubler = createDoubler(4)
doubler.value // 4
doubler.value = 5
doubler.double // 10

EDIT: After giving it another thought I came up with the following solution:

class Doubler {
  constructor(value) {
    this._state = reactive({ value });
  }

  get value() {
    return this._state.value;
  }

  set value(value) {
    return this._state.value = value;
  }

  get double() {
    return this._state.value * 2;
  }
}

If you want to use ref instead of reactive:

class Doubler {
  constructor(value) {
    this._value = ref(value);
  }

  get value() {
    return unref(this._value);
  }

  set value(value) {
    return this._value = value;
  }

  get double() {
    return this.value * 2;
  }
}

Link to CodeSandbox

Upvotes: 4

Related Questions