Reactivity in Vue.js powered by ES6 classes

I am attempting to create a computed property in Vue.js that is associated with an ES6 class. Here is an example of my Vue instance setup:

...
props: ['customClass'],
computed: {
    localClass: {
         get() {
             return this.customClass
         },
         set (value) {
             console.log("changed")
         }
     }
 }
 ...

This is the structure of my class:

class CustomClass {
    constructor () {
        this.selected = false
    }
}

When I try to modify the selected property like this:

this.localClass.selected = true

The setter function is not being triggered, and it seems like the reactivity has been lost. This behavior is confusing to me.

I have also attempted:

Vue.set(this.localClass, 'selected', true)

Although I pass customClass as a prop, even creating a new instance directly in the component does not change the outcome.

I searched through the Vue.js documentation but did not find any specific section addressing reactivity issues with ES6 classes. Can anyone offer insight on why this might be happening and how to ensure my class remains reactive?

Thank you in advance

Answer №1

When you set a computed property like myComputedProperty, it gets triggered every time you assign a value to that property (e.g.

this.myComputedProperty = {something: 'else'}
.

If you're looking for something different, you might need a watcher with deep: true. Here's an example:

watch: {
  localClass: {
    deep: true,
    handler() {
      out.innerHTML += "watched!";
    }
  }
},

Check out the demo below.

class CustomClass {
  constructor() {
    this.selected = false
  }
}
Vue.component('custom', {
  template: '#custom',
  props: ['customClass'],
  computed: {
    localClass: {
      get() {
        return this.customClass
      },
      set(value) {
        out.innerHTML += "changed!\n";
      }
    }
  },
  watch: {
    localClass: {
      deep: true,
      handler() {
        out.innerHTML += "watched!\n";
      }
    }
  },
  methods: {
    assignToSelected() {
      this.localClass.selected = true
    },
    assignToLocalClass() {
      this.localClass = {
        selected: true
      }
    }
  }
});
new Vue({
  el: '#app',
  data: {
    test: new CustomClass()
  },
})
#out { background: black; color: gray; }
span { font-size: x-small; font-family: verdana }
<script src="https://unpkg.com/vue"></script>

<template id="custom">
  <div>
    {{ localClass }}
    <br>
    <button @click="assignToSelected">assignToSelected</button>
    <span>Note: will trigger "watched!" just once, because, since the value is hardcoded in the method (see code) subsequent clicks won't modify the value.</span>
    <br><br>
    <button @click="assignToLocalClass">assignToLocalClass</button>
    <span>Note: assignToLocalClass() will trigger the computed setter, but wont trigger the watcher because the computed setter currently sets nothing, so nothing changed for the watcher to trigger.</span>
  </div>
</template>

<div id="app">
  <custom :custom-class="test"></custom>
</div>

<pre id="out"></pre>

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 should I do when using _.extend() in express - override or add in fields?

When an object is extended by another object with values set for some of the extended fields, will it be rewritten or will the new values be added? For example: const PATCH_REQUEST_SCHEMA = { 'type': 'object', 'title' ...

Error loading custom Javascript in MVC 4 view during the first page load

I'm working on an MVC 4 application that utilizes jQuery Mobile. I have my own .JS file where all the functionality is stored. However, when I navigate to a specific view and check the page source, I notice that all scripts files are loaded except fo ...

Alternating row colors using CSS zebra striping after parsing XML with jQuery

After successfully parsing XML data into a table, I encountered an issue with applying zebra stripe styling to the additional rows created through jQuery. Despite my efforts to troubleshoot the problem in my code, I remain perplexed. Below is a snippet of ...

Mapbox struggling with performance because of an abundance of markers

I have successfully implemented a feature where interactive markers are added to the map and respond to clicks. However, I have noticed that the performance of the map is sluggish when dragging, resulting in a low frame rate. My setup involves using NextJ ...

CORS problem in Chrome when using AngularJS and Symfony 3

I've been dealing with a bug on my backend and frontend for the past week. I created a REST API (php/symfony) to manage books and authors. Initially, I had trouble with cross-origin requests on DELETE, which has been resolved. However, now I am facin ...

Step-by-step guide on incorporating Google Fonts and Material Icons into Vue 3 custom web components

While developing custom web components with Vue 3 for use in various web applications, I encountered an issue related to importing fonts and Google material icons due to the shadow-root. Currently, my workaround involves adding the stylesheet link tag to t ...

The deletion request using the form in Express is experiencing issues and not functioning properly

When attempting to delete data from a database using a form in node.js and express, I am encountering issues with the deletion process. It seems that there are only two methods available - get and post - and no specific delete method. router.js code rout ...

Add the item to a fresh array using the Ajax function

Here is an array that I have: var arrayOfResults = []; // Results after like statement After making a database call, I receive a JSON result like this: [{ "id": "{fcb42c9c-3617-4048-b2a0-2600775a4c34}", "pid": "{34214CCB-90C3-4D ...

Is it necessary to use Hapi.js on the client side in order to establish a websocket connection using the Hapi.js protocol?

Currently, I am in the process of developing an API using Hapi and requiring WebSocket functionality. After some research, it appears that Nes is the preferred choice to integrate with Hapi for this purpose. Fortunately, Nes simplifies the process signific ...

Can you explain the function of a digest attribute?

As a beginner in the world of NextJS, I am currently working on getting my first project ready for production. However, I encountered the following error: Application error: a client-side exception has occurred (see the browser console for more information ...

Check if the value is a string and contains a floating point number; if so, parse and format the float

I need to work on formatting decimal values returned by an API that only responds with strings. The requirement is to add a leading zero but no trailing zeros to any decimal value in the string. If the value is not a float, it should remain unchanged. For ...

What's stopping me from installing the npm stripe checkout package?

After running the command npm install vue-stripe-checkout, I encountered the following error: vue.runtime.esm.js?2b0e:5106 Uncaught TypeError: Cannot read property 'install' of undefined at Function.Vue.use (vue.runtime.esm.js?2b0e:5106) at eval ...

What is the best way to allow my limit to be as greedy as possible?

I'm facing an issue with the code below where it currently only matches MN. How can I modify it to also match KDMN? var str = ' New York Stock Exchange (NYSE) under the symbol "KDMN."'; var patt = new RegExp("symbol.+([ ...

Attempting to achieve a carousel animation using jQuery

Upon loading the page, only one character out of four is displayed. Two arrows are provided - one on the left and one on the right. Clicking on the left arrow causes the current character to fade out and the previous character to fade in. Clicking on the r ...

Rewriting URLs in Angular 2

I am a beginner in Angular 2 and I am currently working on a project that requires URL rewriting similar to that of ' '. In Zomato, when you select a city, the city name appears in the URL like ' ', and when you select a restaurant, t ...

Concerns arise with jQuery grid compatibility in Firefox browsers

I have found an interesting tutorial on draggable image boxes grid at this link. Although everything is functioning properly, I am encountering an issue with the drag function specifically on the home page when using Firefox. As a beginner in jQuery, I am ...

Tips for implementing validation on dynamically inserted fields in a form

My form has two fields, and the submit button is disabled until those fields are filled with some text. However, if I add a third field dynamically using AngularJS, validation will not be supported for the new field. Check out the example here <butto ...

Issue with template updating when utilizing ui-router and ion-tabs in Ionic framework

CODE http://codepen.io/hawkphil/pen/LEBNVB I have set up two pages (link1 and link2) accessible from a side menu. Each page contains 2 tabs: link1: tab 1.1 and tab 1.2 link2: tab 2.1 and tab 2.2 To organize the tabs, I am utilizing ion-tabs for each p ...

Is there a way to use HTML and CSS to switch the style of a dynamic decimal number to either Roman numerals or Katakana characters within a specified HTML element, such as a tag, div

I've searched everywhere but only found guides on list styling and counter styling in CSS that didn't work out. So, for example, I have a number inside an HTML tag that is changed dynamically using Vue Watch. I want to display the number in upper ...

Exploring the significance of a super in Object-Oriented Programming within JavaScript

During my studies of OOP in JS, I encountered the super() method which serves to call the constructor of the parent class. It made me ponder - why is it necessary to invoke the parent class constructor? What significance does it hold for us? ...