Vue composition API and its dynamic reactivity

When setting up, I create something like the following:

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

As I continue working on the component, I am able to call a method of this class using abc.Func(), or access some field. Everything appears to be functioning properly. However, let's consider a scenario: in the class constructor, we create an event listener that listens for a specific event and then sets either true or false for one of the class fields. This is where an issue arises - when trying to display this field in the component that should be changed by the handler, it becomes apparent that the class fields are not reactive. Even though the handler clearly changes the value of the field, this change is not reflected in the component. Fields only become reactive when you also use the reactive keyword for fields within the class. But why is this necessary? I already made the entire class reactive in the setup phase. Why do I also need to specify ref and reactive inside the class?

Code snippet from the component:

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

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

Class definition:

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) // if comment this out, no changes will be visible in the component after setting onPlaying to true
    this.init()
}
    
private init(){
    this.audioPlayer.element.addEventListener('playing', this._onPlaying)
    this.audioPlayer.initialized = true
}
    
private onPlaying() {
    this.audioPlayer.isPlaying = true
}

Answer №1

reactive enables a proxy for the original instance, allowing methods called on the reactive proxy object to receive it as this.

If listeners are established in a constructor, they will be statically linked to utilize the original non-reactive this.

A class must be structured so that it remains unaware of Vue reactive helpers by utilizing this solely for setting initial data in the constructor, not for side effects. Avoid binding callbacks to this within the constructor, including class fields which are essentially part of the constructor body.

The class structure should be:

constructor() {
    this.audioPlayer = {...};
    // this.init()
}
    
init(){
    this.audioPlayer.element.addEventListener('playing', () => this.onPlaying())
    this.audioPlayer.initialized = true
}

To use this structure:

const player = reactive(new AnotherClass())
player.init();

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to arrange two objects depending on the frequency of elements in an array field?

Imagine having two objects, each containing two array fields: const list1 = { name: 'list-1', fruits: ['banana', 'strawberry', 'cherry'], vegs: ['lettuce', 'avocado', 'beans'] }; ...

Using Three.js to ensure that child object3d expands within the boundaries of its parent object

In this scenario, I have 2 Object3Ds with one nested inside the other: var obj1 = new THREE.Object3D(); var obj2 = new THREE.Object3D(); obj1.add(obj2); Assuming obj1 is AxB units wide, how can I instruct obj2 to match that size? Essentially, how can I m ...

Using Vue.js to pass local loop variables to v-bind:style

I am currently iterating through a list and I want to assign a background image based on a property in this list. However, the property is not defined in v-bind:style. How can I overcome this issue? <div class="content" v-bind:key=&q ...

Listening to a song on a webpage while filling out the online form

Seeking advice on integrating audio file selection in form: <form ....> <input type="file" name="file-main" id="file-main" class="inputfile inputfile-3" multiple/> <audio preload="none" src=""> // excluding submission buttons for brevi ...

When using jQuery 1.7 or higher, the on(click..) function may not function correctly on dynamically added <li> elements

Currently, I am working on a dialogue that contains an unordered list with various suggestions. The HTML code for this section is as follows: <ul id="suggestions0"> <li id="suggestion0-0" class="suggestion">BLO</li> <li id="su ...

Utilizing jQuery Ajax to submit multiple forms using a single selector in one go

I'm having an issue with jQuery Ajax involving multiple forms. Each time I execute it, only the top form works properly while the others do not function as expected. Can anyone provide assistance with this? Here is the source code: <form id="form_ ...

Executing a Cron Job several times daily, each and every day

This is my current code snippet: const CronJob = require('cron').CronJob; new CronJob({ cursoronTime: '* * * * *', // every minute onTick: async function() { console.log(&ap ...

sending data from an AngularJS application to an MVC controller in JSON format containing multiple arrays

Currently, I am working on a project that involves using AngularJS and MVC. I am transferring data from an AngularJS controller to my MVC controller using $http.post(). At the moment, I am using a single object or JSON array to retrieve data as follows: pu ...

Are the Bootstrap columns arranged in a vertical stack instead of side by side?

I currently have two large columns that are stacked vertically on top of one another. I want them to be side by side, like | 1 | 2 |, so that the user can view both columns simultaneously. I am seeking tips or suggestions on how to resolve this issue. Whil ...

Parsing through JSON information retrieved from an API

I am working with an API that provides data in two arrays, each containing a category. I need help iterating through and displaying these categories, specifically the ones for Arts and Entertainment. Any assistance would be greatly appreciated. Thank you ...

I am no longer able to connect to mySQL using node js

I recently upgraded my node version, and now I'm facing issues accessing my database through my application. I have tried various solutions such as: - Changing the route to 127.0.0.1. - Adding my port number 3306. - Including socketPath: '/Applic ...

Retrieve JSON data by making a POST request to a website's API

Can you help me retrieve Json data from a website API using JavaScript? I'm trying to fetch quotes from the following website: for my quotes generator page. While I have some understanding of making GET requests, it seems that this API requires POST ...

Vue method not being triggered despite emit in inline template

Trying to figure out what I'm missing here, it seems like this should be the solution: Vue: method is not a function within inline-template component tag Yet, the method still isn't working as expected. <b-table :items="filtered" ...

Utilizing radio buttons to toggle the visibility of multiple content sections

In order to determine which P's display on a page, I need to utilize three radio buttons. The items are fetched from a dynamic database, making the process flexible as there is no fixed number of items. Ideally, I would prefer to stick with JavaScript ...

Locate the iframe that invoked a function within its parent element

There are multiple iframes on a page that showcase ads unicorns and bacon to users. Due to the impossibility of detecting an iframe's domready event from the parent (please correct me if I'm wrong), each iframe contains initialization code like t ...

Which symbol or character corresponds to the public "get symbol" method?

While going through some Typescript code, I came across a line that is giving me trouble to understand. const symbol = Symbol.for('symbolname'); class Something { public get [symbol]() { return true; } ... } I am confused abou ...

Static parameter in Vue router

In my Vue Router, I need to pass specific information through the URL. For example: http://localhost/center/SHOPID/products http://localhost/center/SHOPID/categories http://localhost/center/SHOPID/... The SHOPID value will remain constant throughout th ...

Getting the css property scaleX with JQuery is as simple as executing the

I am struggling to print out the properties of a specific div element using jQuery. My goal is to have the different css properties displayed in an information panel on the screen. Currently, I am facing difficulties trying to show scaleX. Here is my curr ...

A guide on how to perform a PUT or DELETE operation for Azure Table Storage using Node.js

I've been faced with a challenge in my project where I aim to create basic CRUD functionality for Azure Table Storage. However, I'm encountering difficulties in generating a valid SharedKeyLite signature. While I can successfully generate valid ...

Create a Vue application that is built on modules which could potentially be absent

I am currently developing a Vue+Vite app with module-based architecture. I have several Vue components and some parts of the app are functioning correctly. However, I want to ensure that the missing components are not imported or used in the application. H ...