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?
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>
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