I'm relatively new to Vue JS, but feel like I have a relatively good grasp of component hierarchy. Just run into an issue here that I'm a bit confused by and doesn't really match my understanding of what props
should do.
In my parent component, I have a data
attribute called loading
, which is initialised as true
. I also have an attribute called dataItems
, which is initialised as null
but populated by an asynchronous method that calls an API. At the point at which dataItems
is successfully populated, loading
should also be set to false. This API call is made inside the mounted
function.
Everything works as expected at the parent level, but passing these two attributes down to the child component (via props) only seems to pass down their initial state (true
and null
, respectively) and never update them.
As a quick example, I added some <p>
tags to both the parent and child components as a way of outputting the data, here is the shorthand HTML and JS that I used.
Parent Component:
<template>
<p>Loading: {{loading}}</p> // outputs Loading: false
<p>dataItems: {{dataItems}}</p> //outputs JSON string
<ChildComponent :loading="loading" :dataItems="dataItems" />
</template>
<script>
data: function() {
loading: true
dataItems: null
},
methods: {
getDataItems: async function() {
//.. make API call
this.dataItems = response.data
loading = false
}
},
mounted: function() {
this.getDataItems()
}
</script>
Child Component:
<template>
<p>Loading: {{loading}}</p> // outputs Loading: true
<p>dataItems: {{dataItems}}</p> //no output
</template>
<script>
props: ["loading", "dataItems"],
data: function() {
loading: this.loading
dataItems: this.dataItems
},
</script>
So when the parent and child components render together, this is what I see:
Loading: false // from parent
dataItems: {"someJsonString"} // from parent
Loading: true // from child
//from child
I don't understand why the data being passed down isn't being updated, as I kind of understood this to be the point of Vue. Like I say, I'm relatively new to the framework, so there's a chance that I've made a simple mistake.
If anyone can give me a point in the right direction, I'd really appreciate it!
Thanks
CodePudding user response:
your code is right, but it seems that the approach you've decided to implement with props
is not convenient for this situation.
You're (as you mention) initializing your Child state (its data) with props. This approach is useful when you need to change this data from your child component, since you cannot change a prop directly from a child component, only the parent can.
Now, I see that the purpose of your Child component is only showing information that the parent sends (via props). So, you could directly access from your template the props values which are refs (they're reactive).
Child component accessing props in template:
<template>
<p>Loading: {{ loading }}</p>
<p>dataItems: {{ dataItems }}</p>
</template>
<script>
props: ["loading", "dataItems"],
data: function() {
// Use the props directly in your template
},
</script>