Understanding the disparities between a computed property and standard data in Vue.js

Upon observation, I noticed that when a regular property originating from data() and a computed property derived from it are both sent through an event, the former maintains its reactivity while the latter loses it.

To test this scenario, I created the following example (also available on JSFiddle):

const EventBus = new Vue();

Vue.component('comp', {
  data() {
    return {
      arrData: ['a', 'b']
    };
  },
  computed: {
    arrComputed() {
      return this.arrData.map((e) => e.toUpperCase());
    }
  },
  // Template code omitted for brevity...
});

Vue.component('othercomp', {
  data() {
    return {
      items1: [],
      items2: []
    }
  },
  mounted() {
    EventBus.$on('pass', this.receive);
  },
  // Template code omitted for brevity...
});

var app = new Vue({
  el: '#app',
  components:['comp', 'othercomp']
})
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <comp></comp>
  <othercomp></othercomp>
</div>

What causes the difference in behavior between a computed property and a normal property when passed through an event?

While it's advised against sending reactive objects like this, as mentioned in a previous question, I am still curious about the underlying reason for this discrepancy.

Answer №1

It is unlikely that this approach will be effective. By returning the results of the map() function, a duplicate of the reactive array is passed to another component. This duplicate will not respond to changes in the original array as it is an entirely separate array. While the computed property will update when arrData changes, it will not automatically trigger an update in the second component's data array. It may be necessary to have a computed property in both components, and this can be achieved using a mixin or filter for better code reusability.

An alternative could be triggering the event within the computed function, but this method might be considered somewhat unconventional:

arrComputed() { 
   let newArray = this.arrData.map((e) => e.toUpperCase());
   EventBus.$emit('pass', this.arrData, newArray);
   return newArray
}

Answer №2

My observation revealed a scenario where a regular property sourced from data() and a computed property derived from it behaved differently when passed through an event - the former remained reactive while the latter lost its reactivity.

An object variable (such as an Array) holds a reference to the object itself. When one object variable is assigned to another, both variables point to the same object. Any changes made to the object will be reflected in all variables holding references to it.

For instance:

foo = [1];
bar = foo;
foo.push(2);

Both foo and bar, because they are referencing the same object, would now be [1, 2]. Passing values works similarly, but this concept is perhaps easier to grasp with simple assignments.

It becomes evident that:

foo = [1];
bar = foo;
foo = [1, 2];

assigns a new reference to foo, breaking the connection with the array referenced by bar.

In the context of your example, arrComputed generates a new Array object each time arrData changes. Therefore, when passing arrComputed, you are essentially passing the reference created during its last execution. As a result, when arrData changes and a new Array object is created by arrComputed, the recipient of the old reference remains unchanged, causing discrepancies in the reactivity of the Array associated with that particular handle.

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

Create a custom npm package that is compatible with frontend environments like create-react-app. Ensure you have a suitable loader in place to handle the specific file type of the module

After developing a node module and releasing it as a node package, I encountered an issue when trying to use it in frontend applications (specifically with a 'create-react-app'). The error message that appeared stated: Module parse failed: Unexp ...

Carrying over additions in arrays using only Javascript

I'd like to implement a basic array addition with carryover. Additionally, I need to display the carryover and result values. For instance: e.g var input = [[0,0,9],[0,9,9]]; var carryover = []; var result = []; Thank you! ...

What is the process by which GWT functions, specifically in the loading of code into the app.html file?

Can someone please shed some light on the rootPanel within the entryClass in GWT? I'm curious about how the Java code is loaded into the appname.html file via rootPanel. What exactly happens in this process? How does the rootPanel connect with the HTM ...

Exploring Facebook Graph API response with Angular 2 Mapping

I am using HTTP calls to access the Graph API in order to retrieve posts from a Facebook page. Here is the code snippet that fetches an array of posts: let url = 'https://graph.facebook.com/15087023444/posts?fields=likes.limit(0).summary(true),comme ...

Switch Places Once the Video is Complete

Is there a way to make a video play automatically and then redirect to another page once it's finished, without any user interaction? <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transition ...

Launching a React build using Docker on Apache or AWS

I am a beginner to the world of docker and react. My goal is to successfully deploy a production build on AWS. Here are the steps I have taken so far: Created a dockerfile. Built and ran it on the server. npm run and npm run build commands are functionin ...

I am looking to extract only the pairs from the given array, which is represented as `pairsByIndexRaw = [[0, 3], [1, 2], [2, 1], null, [1], false, "whoops"];`

I have a specific array that needs some filtering done. My goal is to remove items that are null, false, and the string "whoops" using JavaScript's filter method. let pairsByIndexRaw = [[0, 3], [1, 2], [2, 1], null, [1], false, "whoops"]; ...

The issue is that the JavaScript output is not being displayed after submitting the HTML

I'm looking to add not only a submit button for the default form action, but also an extra button for a second action. Here is the code I have so far: <html> <head><title></title> <?PHP $Input = ""; if(isset($_POST['I ...

javascript/typescript - conditionally adding an item to an object

If I have an object called userData = {..} and I need to create another object, userDataB, with properties a, b, c, and d from userData but only if they are defined. One way to achieve this is by using the following approach: userDataB = {} if(userData.a ...

Utilize generic types within methods in TypeScript

Here is a snippet of code I'm working on in TypeScript: public static sortByProperty<T>( array: T[], prop: string ): void { var availProps: string[] = Object.getOwnPropertyNames( T ); // or something typeof T, anyway I got error i ...

"Encountered a Chrome RangeError: The call stack size limit was exceeded while utilizing jQuery's $

As part of my job, I am currently evaluating a web application that involves fetching a substantial amount of data from the server. The data is received as a JSON object using the $.ajax function. It contains numerous sub-objects which I convert into array ...

Arrays passed as query parameters to Next.js router.query may result in the value being

When trying to pass objects from an array to another page using router.query, individual objects like router.query.title work as expected. However, when attempting to pass arrays such as router.query.reviews, it returns something like reviews: ['&apos ...

Adjust scale sizes of various layers using a script

I have created a script in Photoshop to adjust the scale size of multiple layers, but I am encountering some inaccuracies. The script is designed to resize both the width and height of the selected layers to 76.39%. However, when testing the script, I foun ...

Converting HTML input to a file using JavaScript

Here is the React.js component code I'm working with: import React, {ChangeEvent, useState} from "react"; import { Button } from "@mui/material"; function UploadCVButton() { const [selectedFile, setSelectedFile] = useState(null ...

I am experiencing technical difficulties with my API resulting in a 500 Internal Server Error

My application involves managing products using CRUD operations. I am able to successfully make an HTTP request to the /api/deleteProduct route in order to delete a product based on its ID. However, the issue lies with creating a new product as the functi ...

How can I extract the JSON value as a string?

I have a scenario where I define two objects. The first object, BOB, has properties "name" with a value of "bob" and "height" with a value of 185. var BOB = { "name": "bob", "height": 185 }; The second object, PROPS, references the height property from ...

Copy the CSS path from Firebug and paste it into the command line suggested

Currently, I am working on customizing the firebug plugin for Firefox. My goal is to enable a feature where when a user Inspects an element and clicks 'Copy CSS path', the CSS path will automatically be pasted onto the command line of the firebug ...

Open in a new tab for enhanced content formatting in Prismic on NextJs

In my Prismic RichText editor, I have included two files (terms and conditions) that I would like to open in a new tab. Unfortunately, Prismic does not offer an option like target _blank for this functionality. I am currently working with NextJs and Tail ...

What is the best way to modify a node_module file consisting of only a few exported variables, which is heavily utilized in the entire module? (with demonstration)

I have integrated a node module with the file structure displayed below. Inside the file node_core_ctx.js, I found this code snippet: const EventEmitter = require('events'); let sessions = new Map(); let publishers = new Map(); let idlePlayers ...

The jQuery Validate Plugin only validates emails when the user moves away from the input field

Resolved: Upon inspecting my version of jquery-validate.js, I discovered that it was missing the onkeyup handler. Despite using version 1.12 Opre, which should have had this functionality according to its Github history from 2013, it seemed like there may ...