I have a posts list component and a post component.
I pass a method to call from the posts list to the post component, so when a button is click it will be called.
But I want to pass the post id when this function is clicked
Code:
let PostsFeed = Vue.extend({ data: function () { return { posts: [....] } }, template: ` <div> <post v-for="post in posts" :clicked="clicked" /> </div> `, methods: { clicked: function(id) { alert(id); } } } let Post = Vue.extend({ props: ['clicked'], data: function () { return {} }, template: ` <div> <button @click="clicked" /> </div> ` }
as you can see in Post component you have a click that runs a method he got from a prop, I want to add a variable to that method.
How do you do that?
The way it works is that you define your data on the parent component and give it a value, then you go to the child component that needs that data and pass the value to a prop attribute so the data becomes a property in the child component. You can use the root component (App.
While you can pass a function as a prop, this is almost always a bad idea. Instead, there is probably a feature of Vue that is designed exactly to solve your problem.
To specify the type of prop you want to use in Vue, you will use an object instead of an array. You'll use the name of the property as the key of each property, and the type as the value. If the type of the data passed does not match the prop type, Vue sends an alert (in development mode) in the console with a warning.
Normally, the click
event handler will receive the event as its first argument, but you can use bind
to tell the function what to use for its this
and first argument(s):
:clicked="clicked.bind(null, post)
Updated answer: However, it might be more straightforward (and it is more Vue-standard) to have the child emit an event and have the parent handle it.
let Post = Vue.extend({ template: ` <div> <button @click="clicked">Click me</button> </div> `, methods: { clicked() { this.$emit('clicked'); } } }); let PostsFeed = Vue.extend({ data: function() { return { posts: [1, 2, 3] } }, template: ` <div> <post v-for="post in posts" @clicked="clicked(post)" /> </div> `, methods: { clicked(id) { alert(id); } }, components: { post: Post } }); new Vue({ el: 'body', components: { 'post-feed': PostsFeed } });
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script> <post-feed></post-feed>
Using Vue 2 and expanding on @Roy J's code above, I created a method in the child component (Post) that calls the prop function and sends back a data object as part of the callback. I also passed in the post as a prop and used its ID value in the callback.
Back in the Posts component (parent), I modified the clicked function by referencing the event and getting the ID property that way.
Check out the working Fiddle here
And this is the code:
let Post = Vue.extend({ props: { onClicked: Function, post: Object }, template: ` <div> <button @click="clicked">Click me</button> </div> `, methods: { clicked() { this.onClicked({ id: this.post.id }); } } }); let PostsFeed = Vue.extend({ data: function() { return { posts: [ {id: 1, title: 'Roadtrip', content: 'Awesome content goes here'}, {id: 2, title: 'Cool post', content: 'Awesome content goes here'}, {id: 3, title: 'Motorcycle', content: 'Awesome content goes here'}, ] } }, template: ` <div> <post v-for="post in posts" :post="post" :onClicked="clicked" /> </div> `, methods: { clicked(event) { alert(event.id); } }, components: { post: Post } }); new Vue({ el: '#app', components: { 'post-feed': PostsFeed } });
And this is the HTML
<div id="app"> <post-feed></post-feed> </div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With