我试图创建这个来添加吐司,但它们以错误的顺序消失,运行代码并单击“添加吐司”按钮 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 秒到 2 秒的时间间隔创建时才会发生该错误。