Sharing an object's attributes as props in Vuejs

Greetings everyone, I am facing some confusion. I am working with two components (child and parent component) where I pass the properties of an object as props

<child :child-data="abc" ></child>
Vue.component('childComponent', {
props: ['childData'],
 data: function(){
    return {
        count:this.childData,// recommend use Vue.util.extend
    }
 },
});

Vue will recursively convert "data" properties of childComponent into getter/setters to make it “reactive”. However, why doesn't it automatically bind data to the template? I have come across recommendations to use Vue.util.extend. Can someone explain why Vue.util.extend is suggested?

UPDATE

In my example: https://jsfiddle.net/hoanghung1995/xncs5qpd/56/

When I set a default value for parentData, childDataA will display it. But when I use v-model to override parentData, then childDataA becomes non-reactive. In such cases, I find myself needing to use "watch" to override "data", similar to what I did for childDataB

For an example using Vue.util.extend: https://jsfiddle.net/sm4kx7p9/3/

Why does Vue.util.extend work fine but not simply using "watch"?

Answer №1

To shed light on the underlying process, Linus Borg provides an insightful response to your inquiry. In essence, the reason why your initial approach fails is due to the fact that data is considered a computed property while props are supplied as primitive types, leading to copies being made by data instead of passing by reference.

An alternative workaround involves defining your childData as computed properties instead of data, like so:

computed: {
    childDataA() {
        return this.childPropsA;
    },
    childDataB() {
        return this.childPropsB;
    }
}

The reason behind using computed lies in these properties now monitoring changes within their dependencies.

A practical demonstration based on your original fiddle:

Vue.component('child', {
  props: ['childPropsA', 'childPropsB'],
  template: "#sub",
  computed: {
    childDataA() {
      return this.childPropsA;
    },
    childDataB() {
      return this.childPropsB;
    }
  }
});
new Vue({
  el: '#app',
  data: {
    parentData: '123'
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
  parentData:{{parentData}}<br>
  <input type="text" v-model="parentData">
  <child :child-props-a="parentData" :child-props-b="parentData"></child>
</div>
<template id="sub">
  <div>
    <p> 1- {{ childDataA }}</p> 
    <p> 2- {{ childDataB }}</p> 
    </div>
</template>

The aforementioned approach yields identical functionality to the combination of data and watch, albeit appearing more cumbersome and adding unnecessary verbosity to your code:

data: function() {
    return {
      childDataA: this.childPropsA,
      childDataB: this.childPropsB
    };
  },
  watch: {
    childPropsA() {
      this.childDataA = this.childPropsA;
    },
    childPropsB() {
      this.childDataB = this.childPropsB;
    }
  }

Vue.component('child', {
  props: ['childPropsA', 'childPropsB'],
  template: "#sub",
  data: function() {
    return {
      childDataA: this.childPropsA,
      childDataB: this.childPropsB
    };
  },
  watch: {
    childPropsA() {
      this.childDataA = this.childPropsA;
    },
    childPropsB() {
      this.childDataB = this.childPropsB;
    }
  }
});
new Vue({
  el: '#app',
  data: {
    parentData: '123'
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
  parentData:{{parentData}}<br>
  <input type="text" v-model="parentData">
  <child :child-props-a="parentData" :child-props-b="parentData"></child>
</div>
<template id="sub">
  <div>
    <p> 1- {{ childDataA }}</p> 
    <p> 2- {{ childDataB }}</p> 
    </div>
</template>

Answer №2

When using Vue, keep in mind that it only watches properties that are reactive by default. Simply passing objects does not make their properties reactive. To ensure reactivity, only pass the specific properties you need as props. If needed, you can force a property to be reactive using Vue.util.extend.

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

Is there a way to effortlessly refresh the WooCommerce cart and receive updated HTML content all in one go?

I am currently working on a customized "mini-cart" that mimics the functionality of the main cart page, including options to adjust quantity, remove items, enter coupons, and remove coupons. I have set up the cart to submit changes via Ajax by listening fo ...

Restricting Checkbox Choices with JavaScript by Leveraging the forEach Function

I am developing a checklist application that limits the user to selecting a maximum of three checkboxes. I have implemented a function to prevent users from checking more than three boxes, but it is not working as expected. The function detects when an ite ...

Generating dynamic JSON objects in Node.js

Here is the initial JSON data I have: { "fullName": "abc", "age": 19, ... } I am looking to utilize Node.js in order to add elements from the above JSON to an object called Variables within the following JSON: { &q ...

What is the most elegant way to retrieve a new item from Firebase and read it?

My goal is to display the result of a successful read on a page, with only one attempt available before the headers are set and the page is sent. I am looking to retrieve one new value, generated after a listener was initiated so as not to pull existing da ...

When evaluating code with eval, properties of undefined cannot be set, but the process works seamlessly without

Currently, I am attempting to utilize the eval() function to dynamically update a variable that must be accessed by path in the format myArray[0][0[1][0].... Strangely enough, when I try this approach, I encounter the following error: Uncaught TypeError: ...

Transferring data from a form to a function in JavaScript

Hey there! I've been working on a form that sends a value to a new window, but for some reason, the value val2 is showing up as null in the new window instead of being passed. Here's my code: function sendValue(value) { ViewImg = window.ope ...

Modifying the anchor link in a pop-up window according to the clicked link using JQuery

I'm currently working on enhancing a forum where we aim to alert users when they click on links that will redirect them to an external website. Right now, my code successfully opens a pop-up window and directs the user to the intended link. However, ...

embedding fashion within offspring component in vue

Looking to apply inline styles to a child component? I am trying to pass properties like height: 200px and overflow-y: scroll. I attempted passing it this way: <Childcomponent style="height: 200px; overflow-y: scroll;" /> but had no luck. ...

Linking Redux to the highest level of my application is not functioning as expected

I have been attempting to troubleshoot this code for quite some time now, but I am struggling to identify the issue at hand. My main goal is to establish a connection between my top-level application and the redux store. However, every time I try, the stor ...

What is the best way to extract all image URLs from a website using JavaScript?

There are various methods to retrieve image src urls using JavaScript, such as utilizing document.images or by targeting all img elements and fetching their src attributes. However, I am currently unable to extract the image urls specified within CSS styl ...

Tips for configuring formik values

index.js const [formData, setFormData] = useState({ product_name: 'Apple', categoryId: '12345', description: 'Fresh and juicy apple', link: 'www.apple.com' }); const loadFormValues = async () => { ...

Issue with React Js: Text Sphere not appearing on page reload

Currently immersed in a react.js environment and eager to incorporate this impressive animated text sphere. Utilizing the TagCloud package for rendering assistance, however, encountered an issue where the text sphere would only display once and disappear u ...

Fixing the "Package Manager Not Found" Issue when Deploying a Next.js Project on Vercel

Having created a website using Next.js and aiming to deploy it on Vercel, I encountered an error during the deployment process despite meticulously following the configuration steps. The error message displayed was: "Unable to determine package manage ...

Download files from Firebase storage to a user's device

I have a variety of files such as images, videos, and audio stored in my firebase storage. My goal is to provide users with the ability to download these files to their computers by clicking on a download button. After reviewing the firebase documentation ...

Guide on implementing hover, click, and other functions with Lottie in NuxtJS

I am currently working with the 'vue-lottie' plugin, but I'm having trouble finding detailed instructions on how to use it. After obtaining JSON animations from Lordicons, I managed to display them correctly. However, I am facing difficulty ...

How do I add a "Switch to Desktop Site" link on a mobile site that redirects to the desktop version without redirecting back to the mobile version once it loads?

After creating a custom mobile skin for a website, I faced an issue with looping back to the mobile version when trying to add a "view desktop version" link. The code snippet below detects the screen size and redirects accordingly: <script type="text/j ...

Having trouble with filtering JSON data in AngularJS?

I'm sorry if this question has already been answered. I tried looking for solutions on other websites, but couldn't understand them. I am attempting to filter JSON data within the ng-repeat function, but whenever I try to input something, it does ...

How to send an image path from a parent component to a child component in Vue.js using Vue CLI

[DONE] A non-comment is a loaded I have recently started working with vue.js using "vue-cli" but I've run into an issue. The goal: I need the parent component to pass the image path as a string to the child component, so that the child can load the ...

What is the best way to deploy a complete stack consisting of a Vue application, .NET Core API, and MariaDB in the cloud

Looking for an affordable hosting solution to showcase my Vue web app, .NET Core API, and MariaDB for a personal portfolio website. The purpose is to display information about myself and my projects when applying for jobs. I need it to be public and secure ...

Having trouble generating a dynamic ref in Vue.js

I am currently working on rendering a list with a sublist nested within it. My goal is to establish a reference to the inner list using a naming convention such as list-{id}. However, I'm encountering difficulties in achieving this desired outcome. B ...