V
V
veryoriginalnickname2021-09-03 23:15:47
Vue.js
veryoriginalnickname, 2021-09-03 23:15:47

How does reactive work in Composition API classes?

In setup I create something like this:

const abc = reactive(new KakoyToClass())
    return {abc}

Further in the component, I can call the method of this class through abc.Func(), or access some field, everything seems to be fine. And now let's imagine the situation: an eventListener is created in the class constructor, which listens to something, and then sets true or false for one of the class fields. And here a problem arises: if you display in the component this very field that the handler should change, you can see that the class fields are not reactive, that is, when the handler unambiguously changed the value of the field, this is not visible in the component. Fields are reactive only when you also enter reactive for fields inside the class. Why? After all, I made the whole class reactive back in setup. Why else do you need to write ref and reactive inside the class?

pieces of code:
<template>
<div style="width: 200px; height: 200px">{{player.audioPlayer.isPlaying}}</div>
</template>

  setup(props) {
    const player = reactive(new AnotherClass())
    return {player}
  },

Class:
private _onPlaying = this.onPlaying.bind(this)
constructor() {
    this.audioPlayer = {
        active: false,
        initialized: false,
        element: new Audio(''),
        isPlaying: false,
        currentPlaying: {
                playlist: [],
                index: 0
            }
        }
    this.audioPlayer = reactive(this.audioPlayer) // если закомментить, не увидим никаких изменений, даже после того, как в onPlaying выставился true
    this.init()
}
    
private init(){
    this.audioPlayer.element.addEventListener('playing', this._onPlaying)
    this.audioPlayer.initialized = true
}
    
private onPlaying() {
    this.audioPlayer.isPlaying = true
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
veryoriginalnickname, 2021-09-04
@veryoriginalnickname

answered on stack


reactive creates a proxy to original instance, so when methods are called on reactive proxy object, they receive it as this.
When listeners are set up in a constructor, they are hard-coded to use original non-reactive this.
In order for a class to be unaware of Vue reactive helpers, it should be designed in a way that allows to not use this in a constructor for setting initial data and not side effects. Callbacks shouldn't be bound to this in constructor, this includes class fields because are syntactic sugar for constructor body.

I seem to understand, but I don't understand.
There is no need to call anything in the constructor, because there is no reactivity. Now, after the reactive class is created, const playermethods can be called through this instance / proxy (in my case), and reactive this or something like that will be passed to these methods. That is:
A proxy is created -> through the proxy, you can call a method (in my case it is init()) that will initialize the listeners, and the callbacks of these listeners should be an arrow function. After these manipulations there will be reactivity without Vyushny pieces.
Why do callbacks have to be arrow functions? What is inside the anonymous callback, what is behind it, i.e. in the called method, this is a proxy, i.e. it turns out that reactivity should be everywhere if the method is called through a proxy. If I call a method through the same proxy, but without an anonymous function in the listener, then there will be no reactivity. What's the catch?
In general, if someone can explain for dummies in Russian, then write in the comments or in the answers.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question