【发布时间】:2021-12-29 09:14:29
【问题描述】:
今天我有一个关于 Vue 的棘手问题,涉及插槽和事件传播。 Here is a codesample
一些背景信息:我有一个订单,其中有 n 个订单位置。这些订单及其位置显示在不同的页面上。为了实现一致的 UI,我为 Order.vue 和 Position.vue 创建了 vue 组件。这些组件不包含任何业务逻辑,只负责在我的应用中保持一致的样式。
此外,我还有一个订单详细信息视图,它显示了我的订单信息及其仓位。
此外,我还有另一个视图,其中显示了相同的信息,并且应该可以选择一些订单/仓位进行取消。
数据包含在页面组件中,并作为道具传递给订单/位置。对于取消页面,我在插槽中传递了复选框组件:
// OrderCancellationPage.vue
<Order v-for="order in orders" :key="order.id" :id="order.id" :positions="order.positions">
<InvoiceCancellationCheckbox :order-id="order.id" @isCancelled="onCancelledEvent($event)" />
</Order>
// Order.vue
<div>
<h3>Order: # {{ id }}</h3>
<slot></slot>
</div>
<OrderPosition
v-for="position in positions"
:key="position.posIndex"
:pos-index="position.posIndex"
>
<InvoiceCancellationCheckbox :orderId="id" :posIndex="position.posIndex" @isCancelled="$emit('isCancelled', $event)"/> //propagate the event to order
</OrderPosition>
// OrderPosition.vue
<div>
<span>Position {{ posIndex }}</span>
<slot></slot>
</div>
我想实现,我的订单/头寸组件不包含任何取消逻辑。因此,InvoiceCancellationCheckbox 正在发出一个事件,如果它已被选中。 Order 和 Position 正在使用 @isCancelled=... 监听此事件,该事件已在我的插槽组件中声明。最后,OrderCancellationPage 应该监听所有这些事件并存储所选订单及其位置。
问题:我收到此警告:
[Vue warn]: Extraneous non-emits event listeners (isCancelled) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. If the listener is intended to be a component custom event listener only, declare it using the "emits" option.
at <Order key="2021-9064-9333-9803" id="2021-9064-9333-9803" positions=
如果我将emits: ['isCancelled'] 添加到Order,我可以解决此警告。但是,订单与取消复选框相结合,这是我不想要的。还有其他解决方案吗?
【问题讨论】:
-
对于您的目的,您会认为自定义 v-model 是“非耦合”的吗?我正在使用可重用的组件,这些组件可能在没有严格上下文的情况下用于各种不同的地方,并且我正在使用自定义 v-model,它使用 prop
modelValue和一个通用的 emitemits: ['update:modelValue']将被发射在更改复选框时,每当我在父组件中需要它时,我都可以查看建模值 -
感谢这工作到目前为止!相同的功能,没有此警告和更易于理解的代码。
-
不客气。很高兴仅凭提示就可以帮助您找到合适的方法
-
也许您想将解决方案发布为其他浏览此页面的人的答案
-
我发布了我的解决方案,但它不适用于 Stackblitz,而是在我的本地机器上,
标签: vue.js vue-component