【发布时间】:2021-02-07 14:08:37
【问题描述】:
我有一个父组件,它遍历一个列表并为每个项目创建一个<ticket-item> 子组件。 <ticket-item> 组件显示一个链接,该链接弹出一个模式并传入该列表项的票证对象。如果用户单击页面上另一个列表中的<appointment-button> 子组件,我还想弹出模式。我在<appointment-button> 中向根实例发出一个事件,并在<ticket-item> 组件中侦听该根事件。下面是每个组件的sn-ps代码:
<ticket-list> 组件列出了每个<ticket-item> 组件:
<tr v-for="ticket in tickets" :key="ticket.id">
<td><ticket-item :ticket="ticket"></ticket-item></td>
<td>{{ticket.amount}}</td>
</tr>
<ticket-item>组件挂载事件:
self = this
this.$root.$on('openTicket-'+this.ticket.id, data => {
console.log('data='+data+', ticket.id='+self.ticket.id)
//event name has ticket id in it, but checking here anyway
if (self.ticket.id==data) {
self.editTicket = true
}
})
<appointment-button> 发出事件的组件:
openTicket() {
this.$root.$emit('openTicket-'+this.appt.ticket.id, this.appt.ticket.id)
}
当我单击约会按钮并发出上面的事件时,我会从已加载的 <ticket-item> 组件中获得此控制台输出:
所以只打印了一行输出,但我的测试中有 8 个<ticket-item> 组件。如果我从事件名称中删除 '-'+ticket.id,则会得到以下控制台输出:
所以 8 行匹配 <ticket-item> 组件的数量,但都使用来自最后一个组件的票证道具的数据。知道我在这里缺少什么吗?为什么挂载的生命周期事件没有从父级(列表)传入的正确“票证”道具?我从我编写的其余代码中知道,从父级传递到组件的任何道具都可以在挂载事件中使用。
更新:
如果我创建约会并签入用户,则会创建一个新的工单项目。现在根监听器更新为使用这个最新的 id。我可以从预约按钮(听众)打开票,但其他人都没有明显工作......
【问题讨论】:
-
我注意到的另一件事是
self的不必要使用。 JS中的Arrow-Functions继承了作用域,所以可以在事件处理函数中使用this -
对于问题本身:可能只是我和迟到的时候,我觉得很难理解。你能提供一个最小的codepen.io/team/Vue 设置吗?
-
我在处理
<SomeItemList>和<SomeItem>时总是做的是$emiting 整个item,因此父级父级拥有该项目的所有数据。您还可以使用方法onOpenTicket(id) { const ticket = this.tickets.filter(ticket => ticket.id === id)[0]; /*do-your-thing-with-ticket*/ }中的$emit('openTicket', this.ticket.id)和<ticket-list>中的<ticket-item @openTicket="onOpenTicket"/>和<ticket-item @openTicket="onOpenTicket"/>
标签: javascript vue.js events components listener