异步实现红绿灯模型

<script setup lang="ts">
import { ref } from "vue";

const lightList = ref(["#fa0110", "#fed31b", "#6fe802"]); //红灯 黄灯 绿灯
let idx = ref(0);
let lightTime = ref(0);

const delay = (ms: number) => new Promise((r) => setTimeout(r, ms));

// 等待切换
const wait = async (light: string, timeout: number) => {
  return new Promise((resolve, reject) => {
    resolve(light);
  }).then(async (res) => {
    idx.value = lightList.value.findIndex((item) => item == res); //颜色切换
    // 倒计时
    while (timeout && timeout > 0) {
      lightTime.value = timeout;
      await delay(1000);
      timeout--;
    }
  });
};
// 红绿灯
const trafficLight = async (lights: Array<number>) => {
  const waitList: Array<Function> = [];
  for (let i = 0; i < 3; i++) {
    const lightItem = () => wait(lightList.value[i], lights[i]);
    waitList.push(lightItem);
  }
  waitList.push(() => wait(lightList.value[1], lights[1])); //绿灯切红灯之前的黄灯
  while (true) {
    // 循环调用切换
    for await (const cb of waitList) {
      await cb();
      lightTime.value = 0; //切换之前把数值置零
      await delay(1000);
    }
  }
};
trafficLight([8, 2, 5]); //红 黄 绿
</script>

<template>
  <div
    v-for="(item, index) in lightList"
    style="display: flex; align-items: center; gap: 16px"
  >
    <div
      class="light"
      :class="{ flicker: idx === index && lightTime <= 3 && idx !== 1 }"
      :style="{ background: idx === index ? item : 'transparent' }"
    ></div>
    <div v-show="idx === index">{{ lightTime }}</div>
  </div>
</template>

<style scoped>
.light {
  width: 50px;
  height: 50px;
  border: 1px solid #666;
  border-radius: 50%;
}
.flicker {
  animation: bounce 1s linear infinite;
}
@keyframes bounce {
  0% {
    opacity: 0.4;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0.4;
  }
}
</style>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值