How to call methods from the parent component in child in vuejs - vue.js

I have a click event and with this click event I want to call function/methods which is in parent component. So the click event in my child component:
<button #click.native="addNew" />
Here is my method:
methods: {
addNew() {
this.$parent.addNew();
},
},
Ad I want to call this function in my parent component:
addNew() {
this.$emit('open');
},
But I a getting an error like: this.$parent.addNew is not a function. How can I fix it?

Based on $emit event in Vue.js: https://vuejs.org/guide/components/events.html
When you emit an event like this: $emit('someEvent'), the parent someEvent function will fire (and also you can pass some parameters).
So you must listen to the 'someEvent' function in parent.
EDIT: this link would be a good example: https://learnvue.co/tutorials/vue-emit-guide

Here is a basic example working with events
Child.vue
<template>
<button #click="$emit('childClick')">click me</button>
</template>
Parent.vue
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
function onChildClick(){
console.log("child has clicked")
}
</script>
<template>
<Child #childClick="onChildClick"></Child>
</template>

Related

how to call child componenet on button click in parent componenet in vuejs

Inside parent component I include child component, I want to render(trigger) the child component when click on button. here is my code
<script>
import childComponenet'../../components/child-component.vue';
export default {
name:'parentComponenet',
components:{
childComponenet
},
methods: {
goToChild(tag){
//go to child component
}
</script>
Use $emit or vuex but if it child and parrent use $emit
What do you actually mean? Show the child when the button on the parent is clicked? Or re-render it?
If you want to show/render it, you can do something like
<template>
<button #click="toggleShowChild">Show Child Component</button>
<ChildComponent v-show="showChild"/>
</template>
<script>
import childComponenet'../../components/child-component.vue';
export default {
name:'parentComponenet',
components:{
childComponenet
},
data () {
return {
showChild: false
}
},
methods: {
toggleShowChild() {
this.showChild = !this.showChild
},
goToChild(tag){
//go to child component
}
</script>
This is a step further where you can toggle the child with the button. If you want the button to only show the child, you can just do #click="showChild = true" on the button, and not write a method at all.
You can do the same with v-if instead of v-show as well. More on the difference between v-if and v-show.

Calling function inside child component without an event?

Currently trying to use a method belonging to the parent
<p class="message-date text-center">
{{ $emit('format_date_day_month_year_time', message.date) }}
</p>
However I am getting the error.
Converting circular structure to JSON
--> starting at object with constructor 'Object'
How can I call a function inside a child component that does not rely on an event? I apologize for asking such a simple question but everything I was able to find on google is using $emit and using an event.
$emit was designed to only trigger an event on the current instance of vue. Therefore, it is not possible to receive data from another component this way.
For your case, I would suggest to use Mixins especially if you need to use certain functions among multiple vue components.
Alternately, let the child component call the the parent through $emit then receive the result from the parent through a prop.
Your code could be something as follows:
Child component
<template>
<p class="message-date text-center">
{{ date }}
</p>
</template>
<script>
export default {
name: 'Child',
props: {
date: String,
},
mounted() {
this.$emit("format-date", message.date);
},
}
</script>
Parent component
<template>
<Child :date="childDate" #format-date="formatChildDate" />
</template>
<script>
import Child from '#/components/Child';
export default {
components: {
Child,
},
data: () => ({
childDate: '',
}),
methods: {
formatChildDate(date) {
this.childDate = this.formatDateDayMonthYearTime(date)
},
formatDateDayMonthYearTime(date) {
//return the formatted date
},
},
}
</script>
with $emit you call a function where the Parent can listento.
where you are using it i would suggest a computed prop of the function.
But back to your Question here is a example of emiting and listen.
//Parent
<template>
<MyComponent #childFunction="doSomethingInParent($event)"/>
</template>
//Child
<template>
<button #click="emitStuff">
</template>
.....
methods:{
emitStuff(){
this.$emit(childFunction, somedata)
}
with the event you can give Data informations to a Parentcomponent.

How i can run method from child component vuejs

I have parent and chidl component... I need to run child method, when i click on button in parent.
Example code:
Parent
<template>
<child-component></child-component>
<button>Open Modal in child Component (set modal = true in child component)</button>
</template>
Child:
<template>
<div v-if="modal">
<button #click="modal = false">Close</button>
</div>
</template>
<script>
export default {
data() {
return {
modal: false
}
}
}
</script>
You can achieve this via different implementations. The most common one is via emit (another alternative is via dispatching actions if you are using the Redux pattern)
First, you want to catch the even on the parent component and emit an event. So this should be your template.
<template>
<child-component></child-component>
<button #click="click">Open Modal in child Component (set modal = true in child component)</button>
</template>
Then you have to emit an event (from the parent component) on the function called when a click was made.
Something like:
click: function() {
this.$emit('update');
}
Lastly, your child component needs to "hear" that event. You can achieve that with something like that on the created function of the child component:
this.$parent.$on('update', this.updateModal);
this.updateModal is a function on your child component which just flips the value of the boolean.
In vue you can pass a function as a prop. So you could add a function to alternate model within your parent component then pass it into your child so it can be used normally. I'll put a simple example below.
small edit, you can bind a class like a hidden/reveal class using the status which is bound to the modal state
// Html
<div id="app">
<child v-bind:on-click="toggleModal" v-bind:status="modal" />
</div>
// Parent Component
var sample = new Vue({
el: '#app',
data: {
modal: false
},
methods: {
toggleModal() {
this.modal = !this.modal
}
}
});
// Child component with function prop
Vue.component('child', {
props: {
onClick: Function,
status: Boolean
}
template: '<button v-on:click="onClick()">Press Me</div>'
});

Having a button on a child component run a function on the parent

I am currently stuck with a simple-looking issue but cannot find the wording.technicality behind solving it.
Essentially, I have a child component "project card" this card is rendered on my home page using
<div v-for="(project, index) in projects" :key="index">
(pulled from an array called "projects" which contain objects).
Anyway, my issue is, I have a button on the "project card" component, and clicking on that I would like to run a function on the "home" page. (as it seems to make sense to control the array from there).
But, how do I do that? How do i make a button pressed on a child component fire a function on the parent?
You need this in your child component:
this.$emit('myEvent')
Then you can do on your parent component:
<my-parent-component v-on:myEvent="doSomething"></my-parent-component>
You can read about firing events at https://v2.vuejs.org/v2/guide/components-custom-events.html . If this is the simple case then using event emiting is fine. But in another cases the better decision is using vuex.
emit the event and register it in the child component using the "emits" property. Listen to the emitted event at the parent element where you have created the child instance and point the event listener to the function you want to execute.
For Eg.
Parent
<template>
<child #close="closeIt"></child>
</template>
<script>
export default {
methods: {
closeIt() {
//DO SOMETHING...
}
}
}
</script>
Child
<template>
<button #click="closeInParent">Close</button>
</template>
<script>
export default {
emits: ["close"],
methods: {
closeInParent() {
this.$emit('close')
}
}
}
</script>

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.