JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.1.4/vue.global.prod.min.js"></script>

<div id="app">
  <div
    v-for="n in messages"
    :key="n.id"
    @click="delMessage(n)"
    @mouseenter="delDeleteTimeout(n)"
    @mouseleave="setDeleteTimeout(n)"
    class="message"
  >
    #{{ n.id }}: {{ n.text }}
    <div class="timer" :class="n.timeout ? 'active' : ''"></div>
  </div>
</div>

CSS

.message {
  border: 1px solid silver;
  padding: 10px;
  margin: 10px;
  background: #ccc;
  cursor: pointer;
  position: relative;
}

.timer {
  display: inline-block;
  position: absolute;
  width: 0;
  height: 2px;
  background: red;
  left: 0;
  bottom: 0;
}

.timer.active {
  width: 100%;
  animation: timer-active 5s linear;
}
@keyframes timer-active {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}

JavaScript

Vue.createApp({
  data: () => ({
    ID: 0,
    messages: [],
  }),
  methods: {
    addMessage(text) {
      const message = {
        id: ++this.ID,
        timeout: null,
        text,
      };

      this.setDeleteTimeout(message);
      this.messages.push(message);
    },
    delMessage(message) {
      const index = this.messages.indexOf(message);
      if (index !== -1) {
        this.delDeleteTimeout(message);
        this.messages.splice(index, 1);
      }
    },
    setDeleteTimeout(message) {
      message.timeout = setTimeout(this.delMessage, 5000, message);
    },
    delDeleteTimeout(message) {
      clearTimeout(message.timeout);
      message.timeout = null;
    },
  },
  mounted() {
    const addMessage = () => {
      this.addMessage(Math.random().toString(16).slice(2));
      setTimeout(addMessage, 1000 + Math.random() * 3000);
    };

    addMessage();
  },
}).mount('#app');