Reputation: 129
I'm trying to get a method to execute on a parent component when a button in one of its child components is clicked. I am using single file components with Webpack. Here's the code for the child component:
<template>
<button v-on:click="add">Click</button>
</template>
<script>
export default {
methods: {
add: () => {
console.log('foo')
this.$dispatch('addClick')
}
}
}
</script>
And the code for the parent:
<template>
<div id="app">
<count :total="total"></count>
<click></click>
</div>
</template>
<script>
import count from './components/count.vue'
import click from './components/click.vue'
export default {
components: {
count,
click
},
data: () => {
return {
total: 0
}
},
methods: {
addToTotal: () => {
console.log('bar')
this.total += 1
}
},
events: {
addClick: 'addToTotal'
}
}
</script>
The count
component is just an h1 element that displays the total
variable. When I click the button, "foo" logs to the console, but "bar" does not and the total doesn't change. Any ideas on what I'm doing wrong? Thanks in advance!
Upvotes: 3
Views: 109
Reputation: 43881
You are using lambda notation for your methods, which is giving them the wrong this
. If you use function
instead, it will work.
Vue.component('click', {
template: '#clicker',
methods: {
add: function() {
console.log('foo')
this.$dispatch('addClick')
}
}
})
new Vue({
el: '#app',
data: () => {
return {
total: 0
}
},
methods: {
addToTotal: function () {
console.log('bar')
this.total += 1
}
},
events: {
addClick: 'addToTotal'
}
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script>
<template id="clicker">
<button v-on:click="add">Click</button>
</template>
<div id="app">
<count :total="total"></count>
<click></click>
{{total}}
</div>
Upvotes: 1
Reputation: 3530
Use two-way .sync
binding type modifier on total
property of count
component so that the value will be updated when parent total
value is changed. Here is an example:
Vue.component('click', {
template: '<button v-on:click="add">Click</button>',
methods: {
add: function () {
this.$dispatch('addClick');
}
}
});
Vue.component('count', {
template: '<h1 v-text="total"></h1>',
props: {
total: {
type: Number,
twoWay: true
}
}
});
new Vue({
el: '#app',
data: {
total: 1
},
methods: {
addTotal: function () {
this.total++;
}
},
events: {
addClick: 'addTotal'
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.25/vue.min.js"></script>
<div id="app">
<count :total.sync="total"></count>
<click></click>
</div>
Upvotes: 0