带有点击监听器的无渲染Vue组件

时间:2018-09-29 21:33:32

标签: vue.js vuejs2 vue-component

我已经阅读了这篇有关无渲染组件的文章:

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

没有渲染的组件看起来像这样:

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

现在,我想使用此无渲染组件,但还向添加到插槽中的内容添加点击侦听器。

就我而言,这将是一个按钮。我的无渲染组件将只包装一个按钮并向其添加一个单击侦听器,从而执行AJAX请求。

如何将点击侦听器添加到正在传递到广告位的元素中?

2 个答案:

答案 0 :(得分:2)

假设您想将点击处理程序绑定在无渲染组件中,我认为从this post开始,您需要克隆传入renderless的vnode,以增强其属性。

请参见createElements Arguments,第二个arg是要增强的对象

  

与您将在模板中使用的属性相对应的数据对象。可选。

console.clear()
Vue.component('renderless', {
  render(createElement) {
    var vNode = this.$scopedSlots.default({})
    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/vue@2.5.17/dist/vue.js"></script>

<div id="app">
  <renderless>
    <button type="button" slot-scope="{props}">Click me</button>
  </renderless>
</div>

答案 1 :(得分:0)

这是解决此问题的一种方法。

您的无渲染组件包装器将由一个N(即发出AJAX请求的函数)道具组成。

action

然后,另一个使用上述包装器的组件将使用Vue.component('renderless-action-wrapper', { props: ['action'], render() { return this.$scopedSlots.default({ action: this.action, }); }, }); 处理程序将可定制的插槽括起来,该处理程序将调用触发时传递的操作。

@click

最后,连接专用版本的包装器。

Vue.component('clickable', {
  props: ['action'],
  template: `
    <renderless-action-wrapper :action="action">
      <span slot-scope="{ url, action }">
        <span @click="action()">
          <slot name="action"></slot>
        </span>
      </span>
    </renderless-action-wrapper>
  `,
});

Here's a live example of the above suggestion you can play around with.