我尝试通过此片段表单Linus Borg的启发来实现一个简单的通知系统:https://jsfiddle.net.net/linusborg/linusborg/wnb6tdg8/
一次添加一个通知时,它可以正常工作,但是当您在第一个通知之前添加第二个通知时,NotificationMessage发出其"关闭通知"事件,但Parent Notificationbox组件不会执行" removEnotification"功能。如果您在通知上使用单击事件,则在发射后调用removeNotification。因此,超时可能存在问题,但我不知道什么。
notificationstore.js
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>
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
<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>
感谢您的帮助
我的小小提琴在那天仍然是我看到的巡回赛:d
那个小提琴仍在使用vue1。在vue 2中,您必须键入列表元素,然后尝试这样做。
但是,key
应该是可靠地识别数据项的独特值。您正在使用不执行此操作的数组索引 - 一旦删除元素,以下项目的索引会更改。
这就是为什么您会看到所看到的行为:Vue无法可靠地删除正确的元素,因为我们的钥匙无法完成他们的工作。
因此,我建议使用nanoid
这样的软件包来创建一个非常唯一的通知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>