Vuejs 2.0 Emit Event from Grand Child to His Grand Parent Component

VueJs 2.0 emit event from grand child to his grand parent component

NEW ANSWER (Nov-2018 update)

I discovered that we could actually do this by leveraging the $parent property in the grand child component:

this.$parent.$emit("submit", {somekey: somevalue})

Much cleaner and simpler.

Vue JS component listens to grandchild component for event

You need to 'daisy-chain' the events, so you would have to put a listener in the Parent-Form that re-emits the event to the Grandparent.

Child(emit) -> Parent(listen, emit) -> Grandparent(listen)

Vuex gets around this issue by using a 'state' as the single source of truth, so only the 'state' needs to be updated to reflect the changes in all connected components.

https://vuex.vuejs.org/

Vuejs emit from grandchild to basic parent

The proper way to overcome this issue in Vue is to use EventBus.

create a new file, and name it eventBus.js and put the following inside

import Vue from 'vue'
export default new Vue()

Then, on the files you want to communicate from, import the file and use as the following

send event:

import EventBus from '../eventBus' 
EventBus.$emit('MESSAGE_NAME', payload)

receive event:

  import EventBus from '../eventBus' 
EventBus.$on('DATA_PUBLISHED', (payload) => {
this.updateData(payload)
})

Vue.js - Emit from grandchild slot component didn't bubble $emit event to parent

BaseDialog emits the close event to its parent, ReviewDialog, which is not listening for it. So you need to listen in ReviewDialog, and re-emit the event to Home:

<BaseDialog
url="@/components/popup/dialog/BaseDialog"
id="review-dialog"
:is-open="isOpen"
:header-text="'REVIEW'"
@close="$emit('close')"> <-- This line is new -->

Another way to do this is to have ReviewDialog pass all its listeners down:

<BaseDialog
url="@/components/popup/dialog/BaseDialog"
id="review-dialog"
:is-open="isOpen"
:header-text="'REVIEW'"
v-on="$listeners"> <-- This line is new -->

Vue.js event emitting from child component to (grand)parent component using global eventbus

The ability to do this goes away with Vue 3. The RFC below mentions the motivation and links to some issues for further help.

https://github.com/vuejs/rfcs/blob/master/active-rfcs/0020-events-api-change.md


I don't think data is the right place for the event bus. I definitely wouldn't use a global mixin for it either.

What I've done in the past is have a simple bus.js file like:

import Vue from 'vue'
export default new Vue()

Then, in any component that needs the bus I just

import bus from './bus.js'

Then I normally do this to emit events.

bus.$emit('foo', whatever)

and this to catch them

created () {
bus.$on('foo', this.someMethod)
}

I prefer to do it in created since that's the earliest step in the lifecycle you can do this.

Also, this issue on github has some very nice examples: https://github.com/vuejs/vuejs.org/pull/435

How Can I capture parent component event in an event emitted by a child event

In CaRow.vue, wrap the event data into a single object:

//this.$emit('update-cellValue', idx, newNumber, oldNumber);
this.$emit('update-cellValue', { idx, newValue: newNumber, oldValue: oldNumber });

Then in the parent template, update the event handler binding to pass the line index (which is idx in this context) and $event (a special variable that stores the emitted event data):

<CaRow @update-cellValue="updateCellVal(idx, $event)">

And update the handler to receive the line index and $event:

export default {
methods: {
updateCellVal(line, { idx, newValue, oldValue }) {
console.log({ line, idx, newValue, oldValue });
}
}
}

Vue 2 cannot detect the change when you directly set an item with the index, so you have to use this.$set():

//this.table[line][idx] = newValue;
this.$set(this.table[line], idx, newValue);

demo

Emit data from Child to parent vue 3

In your search bar, the @click event is never actually invoking the SearchMovies method. Try converting

<button type="submit" class="search-input" @click="searchMovies">...</button>

You're not exporting the function in your setup, at the bottom of setup

setup (_, {emit}) {
const search = ref("")
const movies = ref([])
const SearchMovies = () => {
const value = await fetch(`${process.env.VUE_APP_API_URL_CALL_TWO}${search.value}`)
const data = await value.json()
movies.value = data.contents
search.value = ""
console.log("Movies data from SearchBar.vue when fired up: ", movies.value);
emit('get-movies', movies.value)
}
return { search, movies, SearchMovies }
}

In your fetch statement, you're going to have some async code issue, the fetch statement will run, but then it will skip the await callbacks in favor of doing this.$emit. I'd convert it to
Then, finally, I wouldn't catch the value in Home.vue with

<SearchBar @get-movies="getMovies($event)" />

Instead, just use @get-movies="getMovies" You don't actually need make it call a function, it will just do it on it's own and I find trying to use the event bus causes confusion sometimes. You only need to use it if you have specific data from the template you could pass into it, like in a v-for loop you could pass in the specific object. Let me know if you need me to clarify anything so you can better understand why it's built like this.

<template>
<div class="search-bar">
<input
type="text"
placeholder="Effectuez une recherche"
v-model="search"
/>
<button
class="search-input"
@click="SearchMovies"
>
CHERCHER
</button>
</div>
</template>


Related Topics



Leave a reply



Submit