David J.
David J.

Reputation: 1913

pass event to a rendered component in vue

I'm trying to create a rendered component that will do something when I click on it:

// A normal Vue component using a render function
Vue.component('greeting', {
    methods: {
        sayHello(){
            alert('hello')
        }
        
    },
    render(createElement){
        var self = this
        return createElement(
            'button', 
            {
                '@click': self.sayHello
            },
            'if you click here I will say hello')
    }
})


new Vue({ 
    el: '#app'
})

I'm expecting an alert when I click on the button. As far as I can tell, this will render something like

<button @click="sayHello" />

where the method sayHello is defined in the Vue instance.

Why doesn't this work?

https://codepen.io/dvdgdnjsph/pen/NWNwYOQ

Upvotes: 1

Views: 872

Answers (2)

David J.
David J.

Reputation: 1913

Looks like the passed events need to be specified as 'on', like so:

{ 
  on: {
   click: somefunction
  }

}

https://codepen.io/dvdgdnjsph/pen/NWNwYOQ

https://v3-migration.vuejs.org/breaking-changes/render-function-api.html#_3-x-syntax-2

Upvotes: 1

Vipulw
Vipulw

Reputation: 1283

I have created a working copy of your example in this fiddle. I have modified the way we write click event. Refer below code snippet.

Working Button Click via Render Function

Vue.component('DraggableList', {
  methods: {
    sayHello() {
      alert('hello')
    }
  },
  render: function(createElement) {
    var self = this;
    return createElement(
      'button', // tag name
      {
        on: {
          click: this.sayHello
        }
      }, 'if you click here I will say hello'
    )
  }
})

new Vue({
  el: '#app'
})
.grid{
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    padding: 2em;
    grid-gap: 1em;
}
h1{
    margin: 0;
    padding: 0;
}
.grid input{
    grid-column-start: 1;
    grid-column-end: 3;
    text-align: center;
    font-size: 1.5em;
}
.polite{
    font-family: cursive;
    color: gray;
}
.rude{
    font-family: serif;
    font-weight: bold;
    color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div class="grid">
    <draggable-list></draggable-list>
  </div>
</div>

Upvotes: 0

Related Questions