Vue绑定到动态插槽元素?

Posted

技术标签:

【中文标题】Vue绑定到动态插槽元素?【英文标题】:Vue bind to dynamic slot element? 【发布时间】:2018-11-20 04:07:39 【问题描述】:

我想向组件传递一个插槽中的按钮,该按钮将执行操作。例如具有“添加行”功能的表格。

<my-table :data="data" :cols="cols"> 
   <button slot="add_row"></button>
</my-table>

或者,这个反汇编的警报:

<alert>
   <button slot="close">Remove the alert</button>
</alert>

具有以下模板:

<div class="alert alert-info">
   <slot></slot>
</div>

问题是,我想在组件定义中将事件操作绑定到&lt;slot&gt;ed 按钮,但仍然让组件用户提供自己的按钮(有时甚至是链接,&lt;a&gt; 元素) .

我考虑过为操作按钮使用指令,类似于这个库:https://bootstrap-vue.js.org/docs/components/modal 其中模态按钮有一个v-b-modal 指令。但是不知道怎么做。

更新: 我正在尝试使用指令来实现这一点。这是我到目前为止所拥有的: https://jsfiddle.net/uvd6knLh/

Vue.component('alert', 
    template: `
  <div class="alert alert-info" v-if="show">
    <slot></slot>
  </div>`,

  data() 
        return 
    show: true
    
  ,
  mounted() 
     // directive event
     this.$root.$on("alert:close", () => this.show = false);
  
);

Vue.directive('alert-dismiss', 
   inserted: function(el, binding, vnode) 
    el.addEventListener("click", () => 
        vnode.context.$root.$emit("alert:close");
    );
   
);

所以我监听指令事件。问题是指令事件将导致所有警报组件关闭,正如您在 jsfiddle 中看到的那样。 如何使这种模式发挥作用?

【问题讨论】:

这里是一个使用作用域槽的例子。 codepen.io/Kradek/pen/GGWKPE?editors=1010 如果您想采用这种方法,也可以使用 here is the source 来表示 v-b-modal 指令。 我正在尝试使用指令,但无法弄清楚指令如何与组件通信 他们正在做的是在带有指令的元素被单击时从 $root 发出一个事件,并在模态组件中监听该事件。 谢谢!我正在尝试实现这种模式 - 使用指令,但这不能正常工作,请参阅我的更新。如何使这项工作? 【参考方案1】:

要从子元素 (&lt;my-table&gt;) 向其父元素提供数据和操作,您可以查看 scoped slots。

当子组件有一些与父组件无关的内部状态,或者为子组件提供自定义属性或回调并将标记和样式留给父组件时,作用域插槽非常有效。

但是,在您的情况下,由于它是拥有 data 属性的父级,因此我不确定它是否是最佳解决方案。孩子不应该变异它。

您可以简单地解决父组件上的事件。

【讨论】:

我宁愿把警报的可见性放在父组件上,否则警报总是需要在挂载时设置为可见,而不是由父组件控制。 从 cmets 中,我看到作用域插槽确实解决了问题。我可以传递一个自定义按钮并自己在父级中设置其处理程序。但我实际上不喜欢语法,它不够清楚。我更喜欢采用指令方式。我找不到如何在内部指令和组件之间进行通信 指令在最新版本中发生了变化,不再链接到组件实例,而只链接到 DOM 节点(使它们对于集成 js 库非常有用)。如果你真的想走指令方式,那会很hacky,你可以直接在DOM节点上持久化状态。 你能举个例子,你所说的在DOM节点上保持状态是什么意思?或者以任何方式为组件提供操作指令,正如我在一些 vue 组件中看到的那样。 “导出”处理程序函数的插槽范围方式对我来说似乎不是很直观 我也考虑事件委托(检查 event.target),如果指令太hacky。但我更喜欢直接绑定点击事件

以上是关于Vue绑定到动态插槽元素?的主要内容,如果未能解决你的问题,请参考以下文章

在我的插槽中包装动态添加的子元素

05《Vue 入门教程》Vue 动态样式绑定

vue动态绑定class

Vue3样式引入和使用

jQuery动态创建的元素为啥不能绑定事件

vue给元素动态绑定样式