Pass information from a child component to a parent component with Vue.js - vue.js

Thanks for reading my question.
I have doubts about how to accomplish this in my Vue.js app.
Parent Component: App.vue
Child Components: Loading.vue, ProductsList.vue, NoProductList.vue
The App component is the container. When the page loads, the Loading component is displayed.
The Loading component then checks for products. If there are products the Loading component will return the products as an object.
If there aren't any products the Loading component will return null.
How do I tell the App component which component to use based on the Loading components return value? ie.. Load the ProductsList component if there are products and the NoProduct component when there aren't any products?.
What's the correct way to do notify the parent component about which component it should use in Vue?
Should I use $emit (pass data from child to parent), State Management https://v2.vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch or a Bus component?
Some code...
Loading.vue component (child):
export default {
name: 'loading',
data () {
return {
message: ''
}
},
mounted: function () {
this.loadingProcess();
},
methods: {
loadingProcess: function () {
//process
this.$emit('found-products', 'hola');
}
}
App.vue component (parent):
<template>
<div>
<div id="resultComponent" #found-products="checkProductsList">
<loading></loading>
...
</div>
</div>
</template>
Thanks in advance.

For parent-child interactions, the correct way is for the child to $emit and the parent to set props.
State management and buses are for more complex systems where data must be shared by not-closely-related components.

Related

Trigger child function in parent component

I have a component Base.vue with a child Component that is being displayed by router-view. In the child component I have a function in my setup(), but I want the function to be triggered by menu item in Base.vue. How can I achieve this in vue 3? I can't use vuex for this, because the function uses a lot of google map things and refs.
Base.vue router-view Component <- component contains another component which I need to use the function from in Base.vue
This can be easily implemented through the Vue Composition Api
Assign a ref to your child component as such
<child-component ref="childRef"></child-component>
Declare the ref in your setup function as
import { ref } from 'vue'
export default {
components: { },
props: {},
setup(context,props) {
const childRef = ref(null)
return {childRef}
}
}
You can now call functions in your child component by leveraging your childRef, inside the setup function childRef.value.childFunction() can call functions declared in your child component

Function in Parent never called following an $emit from the Child

I have included an $emit in an axios post of a child component as follows.
axios.post('/api/register', qdata)
.then((response) => {
this.$emit('userUpdated', response.data)
})
In the parent component, I have a div element in the html code containing a v-on, which refers to the userUpdated of the $emit.
<div id="username" v-on:userUpdated="nameUpddated($event)">
<p>{{userid}}</p>
</div>
Finally, the script section of the parent contains the following function called by the v-on.
nameUpddated: function (updatedUser) {
this.userid = updatedUser
}
I have validated that the axios returns a proper value in the Child component. However, the function in the parent never gets called.
In your parent component use child component name instead of div.
Edit: I also added v-if to conditionally show the component.
<child-component v-if="isVisible" id="username" v-on:userUpdated="nameUpddated($event)">
<p>{{userid}}</p>
</child-component>
Also, you need to add a data property to show the component conditionally (initially hidden).
data () {
return {
isVisible: false
}
}
Now, it is up to you at what point you want to show the child component. You would simply change isVisible to true.
After making this change, it should work as expected.
Note: please remember to register the child component properly as well in your parent component:
import childComponent from '#/components/childComponent'
export default {
components: {
childComponent
}
}

Vue.js child component not updated

I have 3 vue.js nested components: main, parent, child.
The parent component load basic data, the child is a simple countdown widget which needs just a data to be configured.
If I set the parent script with static data (IE deadline='2019-12-12') the child show the widget working nice, but if I use dynamic data it generate error.
I'm using computed to pass data to the child component and if I debug it using an alert I see 2 alerts: undefined and then the correct date.
The issue is the first computed data (undefined) crash the widget, so how to create child component using updated (loaded) data?
Parent template:
<template>
<div>
<flip-countdown :deadline=deadline></flip-countdown>
</div>
</template>
Parent Script: it needs to be fixed
export default {
components: {FlipCountdown},
props: ['event'],
computed: {
deadline: function () {
if (typeof(this.event.date)!="undefined") {
//alert(this.event.date)
return this.event.date;
} else {
return "2019-05-21 00:00:00";
}
},
},
Child template: it works
<template>
<div>
<flip-countdown :deadline="deadline"></flip-countdown>
</div>
</template>
Your parent component passes the deadline to its child component before the mounted lifecycle hook fires. Your child component sets its deadline with the initial value of undefined.
You should make deadline a computed property in child component:
computed: {
internalDeadline() {
return this.deadline; // comming from props
}
}
Then you can use internalDeadline in child.
Alternatively, you could wait to render the child component until deadline is defined:
<flip-countdown v-if="deadline !== undefined" :deadline="deadline"></flip-countdown>

Pass change to child components when data value in parent component is changed in vuejs

I want to pass down the changes made in parent component data values to its child components each time the value changes in parent how can i achieve it in vue.js. I am using 3 custom components that have to reflect the current value of the parent component each time. p.s i am new to vue.js
you just need to pass it as a prop. In your template:
<my-component :my-prop="myData" />
and in your script tag:
export default {
data() {
myData: 0,
}
}
Whenever you update this.data, the component will update its view, as the prop will have changed
Data is typically passed one-way from parent to child components via props. See the documentation on this here.
Example:
// register the child component
Vue.component('child', {
props: ['myProp'],
template: '<span>{{ myProp }}</span>'
})
// in parent component
<child :my-prop="hello"></child>

Is there a thing in Vuex that work the same as mapDispatchToProps in Redux?

I was trying to do things like this.updateData() instead of this.$store.dispatch() in a child component, where the updateData is a function inherits from its parent component. Anyone have any idea how to achieve that?
So to update data of parent comp. from child component in Vue we can utilize event bus:
Parent:
<template>
Hi Blake...
<child-component #trigger="updateData()"></child-component>
</template>
<script>
export default {
mounted() {},
methods: {
updateData: function() {
// this will be triggered from child
}
}
}
</script>
Child ( child-component ):
<template>
<button #click="$emit('trigger')">Trigger Parent Function</button>
</template>
<script>
export default {
mounted() {}
}
</script>
Now this only triggers parent function but you can also send data with event that will be received by parent. This is just Vue without Vuex. If I'm wrong and you're not looking for this maybe you want to use Vuex mapActions which can be used to import all Vuex actions you need in your component and use them as this.vuexAction instead of this.$store.dispatch('vuexAction').
I hope I helped. Good luck.