I have a parent component that contains an array and an object:
data() {
return {
products: [],
attributes: {},
}
},
When my parent component is loaded, it gets some AJAX data and populates the variables:
mounted() {
axios.get('/requests/getProducts/' + this.currentCategory).then(response => {
this.products = response.data;
this.createAttributes(); // runs some methods to populate the attributes object
});
},
I then have a child component that I will use to display the attributes. Code from parent template:
<search-attributes :attributes="attributes"></search-attributes>
I have the props declared in my child component:
props: ['attributes'],
So far so good, I can console log the data from parent and child...
Problem is when I try to v-for
the attributes in the child component, it simply returns nothing:
/////////////// this does not render anything ///////////////
<template>
<div>
<div v-for="(value, key) in attributes">
{{ key }}
</div>
</div>
</template>
However, if I pass both the products and attributes variables to the child component, and render products in the child component, attributes will start working!
/////////////// this works /////////////
<template>
<div>
<div v-for="(value, key) in attributes">
{{ key }}
</div>
{{ products }}
</div>
</template>
What the heck is going on?
Do you need to see my parent methods?
I expect you are running into a change detection caveat. Vue cannot detect when you add properties dynamically to an object. In this case, you begin with an empty
attributes
object. If you add properties to it without using $set, then Vue does not understand a change has occurred and will not update the DOM.Update the
createAttributes
to use $set.The reason it works when you pass
products
is Vue can detect the change you make (this.products = response.data
), so it renders the DOM, which shows the latestattributes
as a by product.