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>
问题是,我想在组件定义中将事件操作绑定到<slot>
ed 按钮,但仍然让组件用户提供自己的按钮(有时甚至是链接,<a>
元素) .
我考虑过为操作按钮使用指令,类似于这个库: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】:
要从子元素 (<my-table>
) 向其父元素提供数据和操作,您可以查看 scoped slots。
当子组件有一些与父组件无关的内部状态,或者为子组件提供自定义属性或回调并将标记和样式留给父组件时,作用域插槽非常有效。
但是,在您的情况下,由于它是拥有 data 属性的父级,因此我不确定它是否是最佳解决方案。孩子不应该变异它。
您可以简单地解决父组件上的事件。
【讨论】:
我宁愿把警报的可见性放在父组件上,否则警报总是需要在挂载时设置为可见,而不是由父组件控制。 从 cmets 中,我看到作用域插槽确实解决了问题。我可以传递一个自定义按钮并自己在父级中设置其处理程序。但我实际上不喜欢语法,它不够清楚。我更喜欢采用指令方式。我找不到如何在内部指令和组件之间进行通信 指令在最新版本中发生了变化,不再链接到组件实例,而只链接到 DOM 节点(使它们对于集成 js 库非常有用)。如果你真的想走指令方式,那会很hacky,你可以直接在DOM节点上持久化状态。 你能举个例子,你所说的在DOM节点上保持状态是什么意思?或者以任何方式为组件提供操作指令,正如我在一些 vue 组件中看到的那样。 “导出”处理程序函数的插槽范围方式对我来说似乎不是很直观 我也考虑事件委托(检查 event.target),如果指令太hacky。但我更喜欢直接绑定点击事件以上是关于Vue绑定到动态插槽元素?的主要内容,如果未能解决你的问题,请参考以下文章