I am new to Vue.js and I'm attempting to trigger an event from my grand-child component (card) to the child component (hand) and then to the parent component (main):
card (emit play event) => hand (listen for play event and emit card-play event) => main (listen for card-play event)
The play event should trigger the card-play event.
In the card component, I emit a "play" event when the card is clicked. In my hand component, I listen for the "play" event in order to emit the "card-play" event to the parent (main). However, neither events are being emitted nor are the elements (button element) working.
If I directly include the card component in the main component, everything works fine. But when I add another component (hand) between them, nothing works as expected.
Here is my code:
new Vue({
name: 'game',
el: '#app',
data: state,
template: `
<div id="#app">
<card :def="testCard" @click.native="handlePlay2" />
<transition name='hand'>
<hand :cards="testHand" v-if="!activeOverlay" @card-play="testPlayCard" />
</transition>
</div>
`,
methods: {
testPlayCard(card) {
console.log('You played a card!');
},
handlePlay2() {
console.log('You played a card!');
}
},
created() {
this.testHand = this.createTestHand();
},
computed: {
testCard () {
return cards.archers
},
}
});
Here are the components:
/* ----- CARD COMPONENT ----- */
Vue.component('card', {
props: ['def'],
template: `
<div class="card" :class="'type-' + def.type" v-on:click.native="firePlayEvent">
<div class="title">{{ def.title }}</div>
<img class="separator" src="svg/card-separator.svg" />
<div class="description">
<div v-html="def.description"></div>
</div>
<div class="note" v-if="def.note">
<div v-html="def.note"></div>
</div>
<button>bos</button>
</div>
`,
methods: {
firePlayEvent: function() {
this.$emit('play');
console.log("play event is emitted???")
}
},
});
/* ----- HAND COMPONENT ----- */
Vue.component('hand', {
props: ['cards'],
template: `
<div class="hand">
<div class="wrapper">
<!-- Cards -->
<card v-for="card in cards" :key="card.uid" :def="card.def" @play=handlePlay(card) />
</div>
</div>
`,
methods: {
handlePlay(card) {
this.$emit('card-play', card);
console.log("custom event card-play>>");
}
},
});
I am storing all data in state.js:
// Some useful variables
var maxHealth = 10
var maxFood = 10
var handSize = 5
var cardUid = 0
var currentPlayingCard = null
// The consolidated state of our app
var state = {
// World
worldRatio: getWorldRatio(),
// TODO Other things
turn: 1,
//
players: [
{ name : 'Humoyun' },
{ name : 'Jamshid' },
],
//
currentPlayerIndex: Math.round(Math.random()),
//
testHand: [],
//
activeOverlay: null,
//
}