vue.js $在短时间内多次呼叫时,父母不会收到发射



我尝试通过此片段表单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>

最新更新