在短时间内多次调用时,家长未收到vue.js$emit
我试图用通知存储实现一个简单的通知系统,其灵感来源于Linus Borg的这段代码: 一次添加一个通知可以正常工作,但在第一个通知消失之前添加第二个通知时,notificationMessage会发出“关闭通知”事件,但父notificationBox组件不会执行“removeNotification”功能。如果在通知上使用click事件,则会在发出后调用removeNotification。所以超时可能有问题,但我不知道是什么 NotificationStore.js在短时间内多次调用时,家长未收到vue.js$emit,vue.js,vuejs2,settimeout,Vue.js,Vuejs2,Settimeout,我试图用通知存储实现一个简单的通知系统,其灵感来源于Linus Borg的这段代码: 一次添加一个通知可以正常工作,但在第一个通知消失之前添加第二个通知时,notificationMessage会发出“关闭通知”事件,但父notificationBox组件不会执行“removeNotification”功能。如果在通知上使用click事件,则会在发出后调用removeNotification。所以超时可能有问题,但我不知道是什么 NotificationStore.js class Notifi
class NotificationStore {
constructor () {
this.state = {
notifications: []
}
}
addNotification (notification) {
this.state.notifications.push(notification)
}
removeNotification (notification) {
console.log('remove from store')
this.state.notifications.splice(this.state.notifications.indexOf(notification), 1)
}
}
export default new NotificationStore()
App.vue
<template>
<div id="app">
<notification-box></notification-box>
<div @click="createNotif">
create new notification
</div>
</div>
</template>
<script>
import notificationMessage from './components/notificationMessage.vue'
import notificationBox from './components/notificationBox.vue'
import NotificationStore from './notificationStore'
export default {
name: 'app',
methods: {
createNotif () {
NotificationStore.addNotification({
name: 'test',
message: 'this is a test notification',
type: 'warning'
})
}
},
components: {
notificationMessage,
notificationBox
}
}
</script>
创建新通知
从“./components/notificationMessage.vue”导入notificationMessage
从“./components/notificationBox.vue”导入notificationBox
从“./NotificationStore”导入NotificationStore
导出默认值{
名称:“应用程序”,
方法:{
createNotif(){
NotificationStore.addNotification({
名称:'测试',
消息:“这是一个测试通知”,
类型:“警告”
})
}
},
组成部分:{
通知信息,
通知箱
}
}
notificationBox.vue
<template>
<div :class="'notification-box'">
<notification-message v-for="(notification, index) in notifications" :notification="notification" :key="index" v-on:closeNotification="removeNotification"></notification-message>
</div>
</template>
<script>
import notificationMessage from './notificationMessage.vue'
import NotificationStore from '../notificationStore'
export default {
name: 'notificationBox',
data () {
return {
notifications: NotificationStore.state.notifications
}
},
methods: {
removeNotification: function (notification) {
console.log('removeNotification')
NotificationStore.removeNotification(notification)
}
},
components: {
notificationMessage
}
}
</script>
从“./notificationMessage.vue”导入notificationMessage
从“../NotificationStore”导入NotificationStore
导出默认值{
名称:'notificationBox',
数据(){
返回{
通知:NotificationStore.state.notifications
}
},
方法:{
removeNotification:功能(通知){
console.log('removeNotification')
NotificationStore.removeNotification(通知)
}
},
组成部分:{
通知信息
}
}
notificationMessage.vue
<template>
<div :class="'notification-message ' + notification.type" @click="triggerClose(notification)">
{{ notification.message }}
</div>
</template>
<script>
export default {
name: 'notificationMessage',
props: {
notification: {
type: Object,
required: true
},
delay: {
type: Number,
required: false,
default () {
return 3000
}
}
},
data () {
return {
notificationTimer: null
}
},
methods: {
triggerClose (notification) {
console.log('triggerClose')
clearTimeout(this.notificationTimer)
this.$emit('closeNotification', notification)
}
},
mounted () {
this.notificationTimer = setTimeout(() => {
console.log('call trigger close ' + this.notification.name)
this.triggerClose(this.notification)
}, this.delay)
}
}
</script>
{{notification.message}}
导出默认值{
名称:“notificationMessage”,
道具:{
通知:{
类型:对象,
必填项:true
},
延迟:{
类型:数字,
必填项:false,
默认值(){
返回3000
}
}
},
数据(){
返回{
notificationTimer:空
}
},
方法:{
触发关闭(通知){
console.log('triggerClose')
clearTimeout(此.notificationTimer)
此.$emit('closeNotification',notification)
}
},
挂载(){
this.notificationTimer=setTimeout(()=>{
console.log('call trigger close'+this.notification.name)
this.triggerClose(this.notification)
},这个。延迟)
}
}
谢谢你的帮助我以前的小提琴仍然在我看到的地方演奏:D 那把小提琴仍在使用Vue 1。在Vue 2中,您必须为列表元素设置关键帧,并且您已经尝试过这样做 但是,
键
应该是可靠地标识数据项的唯一值。您使用的是数组索引,而数组索引并没有做到这一点——一旦删除一个元素,以下项目的索引就会改变
这就是为什么您会看到所看到的行为:Vue无法可靠地删除正确的元素,因为我们的键不起作用
因此,我建议使用一个包,比如为每个通知创建一个真正唯一的id,但一个简单的计数器也可能会起作用:
let _id = 0
class NotificationStore {
constructor () {
this.state = {
notifications: []
}
}
addNotification (notification) {
this.state.notifications.push({ ...notification, id: _id++ })
}
removeNotification (notification) {
console.log('remove from store')
this.state.notifications.splice(this.state.notifications.indexOf(notification), 1)
}
}
在通知组件中:
<notification-message
v-for="(notification, index) in notifications"
:notification="notification"
:key="notification.id"
v-on:closeNotification="removeNotification"
></notification-message>
我以前的小提琴仍然在我看到的地方演奏:D 那把小提琴仍在使用Vue 1。在Vue 2中,您必须为列表元素设置关键帧,并且您已经尝试过这样做 但是,
键
应该是可靠地标识数据项的唯一值。您使用的是数组索引,而数组索引并没有做到这一点——一旦删除一个元素,以下项目的索引就会改变
这就是为什么您会看到所看到的行为:Vue无法可靠地删除正确的元素,因为我们的键不起作用
因此,我建议使用一个包,比如为每个通知创建一个真正唯一的id,但一个简单的计数器也可能会起作用:
let _id = 0
class NotificationStore {
constructor () {
this.state = {
notifications: []
}
}
addNotification (notification) {
this.state.notifications.push({ ...notification, id: _id++ })
}
removeNotification (notification) {
console.log('remove from store')
this.state.notifications.splice(this.state.notifications.indexOf(notification), 1)
}
}
在通知组件中:
<notification-message
v-for="(notification, index) in notifications"
:notification="notification"
:key="notification.id"
v-on:closeNotification="removeNotification"
></notification-message>
非常感谢您的帮助:)以及初始代码。非常感谢您的帮助:)以及初始代码。