代码之家  ›  专栏  ›  技术社区  ›  Stephan-v

带有单击侦听器的无渲染Vue组件

  •  3
  • Stephan-v  · 技术社区  · 6 年前

    我读过这篇关于无渲染组件的文章:

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

    无渲染组件大致如下所示:

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

    现在,我想使用这个无渲染组件,但也要添加一个click侦听器到正在传递到槽中的任何内容。

    在我的情况下,它将是一个按钮。我的无渲染组件只需包装一个按钮并向其添加一个click侦听器,该侦听器反过来执行AJAX请求。

    我该如何向正在传递到槽中的元素添加click侦听器?

    2 回复  |  直到 6 年前
        1
  •  4
  •   Richard Matsen    4 年前

    假设您想在无呈现组件中绑定click处理程序,我认为 this post 您需要克隆传入的vnode renderless ,以提高其性能。

    看到了吗 createElements Arguments ,第二个arg是要增强的对象

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

    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/vue@2.6.11/dist/vue.js"></script>
    
    <div id="app">
      <renderless>
        <button type="button" slot-scope="{props}">Click me</button>
      </renderless>
    </div>
        2
  •  0
  •   miqh    6 年前

    有一个办法。

    您的无渲染组件包装将由一个 action (即发出AJAX请求的函数)prop。

    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>
      `,
    });
    

    <clickable :action="doAjaxRequest">
      <button type="button" slot="action">Button</button>
    </clickable>
    

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