Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Renderless Vue component with a click listener

Tags:

I have read this post which goes in depth about renderless components:

https://adamwathan.me/renderless-components-in-vuejs/

A renderless component would pretty much look like this:

export default {
  render() {
    return this.$scopedSlots.default({})
  },
}

Now I would like to use this renderless component but also add a click listener to whatever is being passed into the slot.

In my case it would be a button. My renderless component would simply wrap a button and add a click listener to it, which in turn performs an AJAX request.

How would I go about adding a click listener to the element that is being passed into the slot?

like image 271
Stephan-v Avatar asked Sep 29 '18 21:09

Stephan-v


1 Answers

Assuming you want to bind the click handler within the renderless component, I think from this post that you need to clone the vnode passed in to renderless, in order to enhance it's properties.

See createElements Arguments, the second arg is the object to enhance

A data object corresponding to the attributes you would use in a template. Optional.

console.clear()
Vue.component('renderless', {
  render(createElement) {
    var vNode = this.$scopedSlots.default()[0]
    var children  = vNode.children || vNode.text
    const clone = createElement(
      vNode.tag, 
      {
        ...vNode.data, 
        on: { click: () => alert('clicked') }
      },
      children
    )
    return clone
  },
});
new Vue({}).$mount('#app');
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>

<div id="app">
  <renderless>
    <button type="button" slot-scope="{props}">Click me</button>
  </renderless>
</div>
like image 146
Richard Matsen Avatar answered Oct 04 '22 23:10

Richard Matsen