元素以错误的顺序消失,在 vue.js 中

问题描述 投票:0回答:0

我试图创建这个来添加吐司,但它们以错误的顺序消失,运行代码并单击“添加吐司”按钮 3 次,它们消失的顺序是 1-3-2 而不是 1-2- 3.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title></title>
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
  <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
  <script src="https://unpkg.com/[email protected]/dist/vue.global.prod.js"></script>
  <script>const rid = _ => "rid_" + Array.from(crypto.getRandomValues(new BigUint64Array(2))).map(item => item.toString(36)).join("");</script>
  <script>const ider = query => "#"+$(query).last().attr(`id`, rid()).attr(`id`);</script>
  <style>
    component { display: none; }
    app { display: block; }
  </style>
</head>
<body>
<style>
  @keyframes vbst_toast-show {
    0%   { opacity: 0%;   }
    100% { opacity: 100%; }
  }
  @keyframes vbst_toast-fade {
    0%   { opacity: 100%; }
    100% { opacity: 0%;   }
  }
  .vbst_toast-show {
    animation-name: vbst_toast-show;
    animation-duration: 1s;
    animation-play-state: running;
    animation-fill-mode: forwards;
  }
  .vbst_toast-fade {
    animation-name: vbst_toast-fade;
    animation-duration: 1s;
    animation-play-state: running;
    animation-fill-mode: forwards;
  }
</style>
<component name="bs-alert">
  <div :id="toast.id" class="toast show" :class="[animation]">
    <div class="toast-header">
      <i class="bi" :class="['bi-'+toast.icon,'text-'+toast.color]"></i>
      <strong class="ms-2" :class="['text-'+toast.color]">{{toast.title}}</strong>
      <small  class="ms-auto">{{toast.time}}</small>
      <button class="ms-2 btn btn-link text-danger p-0 bi bi-x"></button>
    </div>
    <div class="toast-body">{{toast.body}}</div>
  </div>
</component>
<app>
  <bs-alert 
    v-for="toast in toasts"
    :toast="toast"
  />
</app>
<script>
  APP$VUEBS_TOASTER = Vue.createApp({
    data() {
      return {
        title: "<%- title %>",
        toasts: []
      }
    },
    components: {
      'bs-alert': {
        props: ['toast'],
        template: ider(`component[name="bs-alert"]`),
        data() {
          return {
            animation: 'vbst_toast-show'
          }
        },
        mounted() {
          setTimeout(() => {
            this.animation = 'vbst_toast-fade';
          }, 6000);
        }
      }
    },
    methods: {
      addToast(toast) {
        this.toasts.push(toast);
        setTimeout(_=>{ this.toasts.shift() }, 7000);
      }
    }
  }).mount(ider(`app`))
</script>
<button style="position: fixed; bottom: 0; right: 0;">add toast</button>
<script>
  $("button").last().on("click", function() {
    APP$VUEBS_TOASTER.addToast({ 
      id: rid(),
      color: "primary", 
      icon: "alarm", 
      title: "title", 
      body: `hello world!`
    });
  })
</script>
</body>
</html>

这个想法是,应用程序有一个方法

addToast
接收一个 json 对象,该对象被插入到数组中
toasts
并且因为应用程序上的组件
bs-toast
v-for="toast in toast"
它会在页面,除了添加 toast 之外,方法
addToast
还添加了一个 setTimeout 函数,通过在 7000 毫秒后执行
this.alerts.shift()
来删除警报中最旧的元素(警报)。我想让它看起来更流畅,所以我创建了两个 css 动画,一个是让警报元素“显示”和“淡出”,我所做的是在 data() 返回中定义一个变量“动画”,具有默认值在展示动画中,该变量作为一个类添加到组件中,然后我在组件上的挂载函数中添加了一个 setTimeout 函数,以在 6 秒后将动画更改为“淡入淡出”,所以:

  1. 调用 addToast 方法并将警报添加到警报
  2. 警报有一个动画“显示”,使其看起来很流畅
  3. 添加警报后 6 秒后,动画变为“淡出”。
  4. 添加警报 7 秒后从“警报”中删除。

只有当警报以 1 秒到 2 秒的时间间隔创建时才会发生该错误。

javascript jquery vue.js vuejs3 toast
© www.soinside.com 2019 - 2024. All rights reserved.