最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3動(dòng)態(tài)倒計(jì)時(shí)的代碼實(shí)現(xiàn)

 更新時(shí)間:2024年09月24日 09:44:54   作者:碼農(nóng)研究僧  
在使用Vue框架開(kāi)發(fā)Web應(yīng)用時(shí),倒計(jì)時(shí)功能是一個(gè)常見(jiàn)的需求,它可以在一定時(shí)間內(nèi)重復(fù)執(zhí)行某些操作,比如防止用戶重復(fù)提交表單、限制投票次數(shù)、實(shí)現(xiàn)驗(yàn)證碼獲取等功能,所以本文給大家介紹了Vue3動(dòng)態(tài)倒計(jì)時(shí)的代碼實(shí)現(xiàn),需要的朋友可以參考下

1. Demo

給一版初始的Demo,在給一版實(shí)戰(zhàn)中的Demo

基本知識(shí)點(diǎn):

  • Vue 3 的響應(yīng)式原理:Vue 3 使用 reactive 和 ref 創(chuàng)建響應(yīng)式數(shù)據(jù),數(shù)據(jù)的變化會(huì)自動(dòng)觸發(fā)視圖更新
  • setup 函數(shù):Vue 3 引入了 Composition API,其中的 setup 函數(shù)是組件邏輯的入口
  • watch 偵聽(tīng)器:用于偵聽(tīng)響應(yīng)式數(shù)據(jù)的變化,在倒計(jì)時(shí)場(chǎng)景中可以用于監(jiān)聽(tīng)時(shí)間的變化
  • 生命周期鉤子:如 onMounted 和 onUnmounted 用于在組件掛載和銷(xiāo)毀時(shí)啟動(dòng)和清理倒計(jì)時(shí)
  • setInterval 和 clearInterval:用于每隔一段時(shí)間執(zhí)行倒計(jì)時(shí)任務(wù)

Demo:

<template>
  <div>
    <table>
      <thead>
        <tr>
          <th>任務(wù)名稱(chēng)</th>
          <th>剩余時(shí)間</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="task in tasks" :key="task.id">
          <td>{{ task.name }}</td>
          <td>{{ task.remainingTime }} 秒</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script setup>
import { reactive, onMounted, onUnmounted } from 'vue';

const tasks = reactive([
  { id: 1, name: '任務(wù)A', remainingTime: 60 },
  { id: 2, name: '任務(wù)B', remainingTime: 120 },
  { id: 3, name: '任務(wù)C', remainingTime: 180 },
]);

let intervalId;

onMounted(() => {
  intervalId = setInterval(() => {
    tasks.forEach(task => {
      if (task.remainingTime > 0) {
        task.remainingTime -= 1;
      }
    });
  }, 1000);
});

onUnmounted(() => {
  clearInterval(intervalId);
});
</script>

2. 實(shí)戰(zhàn)Demo

本身倒計(jì)時(shí)的某一列時(shí)間是固定的,那就不需要通過(guò)后端來(lái)獲取動(dòng)態(tài)數(shù)據(jù),只需要基于appointmentEndTime和當(dāng)前時(shí)間來(lái)計(jì)算倒計(jì)時(shí)。對(duì)于超過(guò)當(dāng)前時(shí)間的數(shù)據(jù),可以直接顯示“已結(jié)束”或其他提示

以下是基于Vue 3的倒計(jì)時(shí)實(shí)現(xiàn)方式,重點(diǎn)是如何根據(jù)appointmentEndTime與當(dāng)前時(shí)間來(lái)動(dòng)態(tài)更新表格的倒計(jì)時(shí)列

  • appointmentEndTime 固定:你可以直接在表格數(shù)據(jù)中使用固定的時(shí)間戳。
  • 倒計(jì)時(shí)邏輯:通過(guò)setInterval每秒更新一次倒計(jì)時(shí),但如果appointmentEndTime已經(jīng)過(guò)期,就不再更新。
  • 無(wú)須請(qǐng)求后端:無(wú)需額外API請(qǐng)求,直接使用appointmentEndTime進(jìn)行計(jì)算
<template>
  <div>
    <el-table :data="tableData" style="width: 100%">
      <!-- 審核時(shí)間列 -->
      <el-table-column
        label="審核時(shí)間"
        align="center"
        prop="appointmentReviewTime"
        :formatter="dateFormatter"
        width="170px"
      />

      <!-- 還柜時(shí)間列 -->
      <el-table-column
        label="還柜時(shí)間"
        align="center"
        prop="appointmentEndTime"
        :formatter="dateFormatter"
        width="170px"
      />

      <!-- 倒計(jì)時(shí)列 -->
      <el-table-column label="倒計(jì)時(shí)" align="center" width="170px">
        <template #default="scope">
          <span>{{ formatCountdown(scope.row.appointmentEndTime) }}</span>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
import { ref, onMounted, onBeforeUnmount } from 'vue';

export default {
  setup() {
    // 表格數(shù)據(jù),appointmentEndTime 是固定的時(shí)間
    const tableData = ref([
      {
        appointmentReviewTime: '2024-09-20 12:00:00',
        appointmentEndTime: '2024-09-20 14:00:00' // 固定時(shí)間
      },
      {
        appointmentReviewTime: '2024-09-21 15:00:00',
        appointmentEndTime: '2024-09-21 17:00:00' // 固定時(shí)間
      }
    ]);

    // 倒計(jì)時(shí)格式化函數(shù)
    const formatCountdown = (endTime) => {
      const now = new Date().getTime();
      const endTimestamp = new Date(endTime).getTime();
      const remainingTime = endTimestamp - now;

      // 如果已過(guò)期,返回 "已結(jié)束"
      if (remainingTime <= 0) {
        return '已結(jié)束';
      }

      const hours = Math.floor(remainingTime / (1000 * 60 * 60));
      const minutes = Math.floor((remainingTime % (1000 * 60 * 60)) / (1000 * 60));
      const seconds = Math.floor((remainingTime % (1000 * 60)) / 1000);

      return `${hours}小時(shí) ${minutes}分鐘 ${seconds}秒`;
    };

    // 使用 setInterval 動(dòng)態(tài)更新倒計(jì)時(shí)
    const intervalId = ref(null);
    onMounted(() => {
      intervalId.value = setInterval(() => {
        // 強(qiáng)制觸發(fā)視圖更新
        tableData.value = [...tableData.value];
      }, 1000);
    });

    // 清除計(jì)時(shí)器
    onBeforeUnmount(() => {
      clearInterval(intervalId.value);
    });

    return {
      tableData,
      formatCountdown
    };
  }
};
</script>

如果不會(huì)出現(xiàn)自動(dòng)更新視圖的,需要排查下瀏覽器的終端是否會(huì)有輸出異常

實(shí)戰(zhàn)中的Bug:(錯(cuò)誤信息 queryParams.value is not iterable 表示在某處嘗試遍歷或解構(gòu)了queryParams,但是它不是可迭代的對(duì)象,確保queryParams是一個(gè)對(duì)象或數(shù)組,不能將非迭代對(duì)象進(jìn)行迭代操作)

3. 拓展Demo

appointmentEndTime這個(gè)是timestamp時(shí)間,也就是設(shè)定的未來(lái)時(shí)間
但是我要已過(guò)期,或者超過(guò)當(dāng)前時(shí)間的 都顯示 重新預(yù)約

那么只需要在超過(guò)當(dāng)前時(shí)間或已過(guò)期的情況下顯示“重新預(yù)約”

  • 修改 formatCountdown 函數(shù)
    在 formatCountdown 函數(shù)中添加一個(gè)返回值,用于標(biāo)記該時(shí)間是否已經(jīng)過(guò)期
const formatCountdown = (endTime) => {
  const now = new Date().getTime();
  const endTimestamp = new Date(endTime).getTime();
  const remainingTime = endTimestamp - now;

  // 如果已過(guò)期,返回 "已過(guò)期" 并標(biāo)記為需要重新預(yù)約
  if (remainingTime <= 0) {
    return { text: '已過(guò)期', isExpired: true };
  }

  const hours = Math.floor(remainingTime / (1000 * 60 * 60));
  const minutes = Math.floor((remainingTime % (1000 * 60 * 60)) / (1000 * 60));
  const seconds = Math.floor((remainingTime % (1000 * 60)) / 1000);
  // 分時(shí)秒的格式化
  return { text: `${hours}小時(shí) ${minutes}分鐘 ${seconds}秒`, isExpired: false };
};
  • 修改模板邏輯

使用 formatCountdown 函數(shù)的返回值來(lái)判斷是否顯示 “重新預(yù)約”

<el-table-column label="還柜剩余時(shí)間" align="center" width="155px">
  <template #default="scope">
    <span>{{ formatCountdown(scope.row.appointmentEndTime).text }}</span>
  </template>
</el-table-column>

<el-button
  link
  type="primary"
  @click="showRejectionReason(scope.row.id)"
  v-if="scope.row.appointmentEndTime !== null && formatCountdown(scope.row.appointmentEndTime).isExpired"
  v-hasPermi="['dangerous:appointment-commission:query']"
>
  重新預(yù)約
</el-button>

為了在等于當(dāng)前時(shí)間點(diǎn)的時(shí)候觸發(fā)后端請(qǐng)求

可以修改倒計(jì)時(shí)的函數(shù)如下:

// 倒計(jì)時(shí)格式化函數(shù)
const formatCountdown = (endTime,id) => {
  const now = new Date().getTime();
  const endTimestamp = new Date(endTime).getTime();
  const remainingTime = endTimestamp - now;

  // 設(shè)置一個(gè)容忍時(shí)間范圍(例如,1秒)
  const tolerance = 1000; // 1秒

  
  // 當(dāng)時(shí)間接近到達(dá)時(shí),發(fā)送請(qǐng)求到后端更新?tīng)顟B(tài)
  if (remainingTime <= tolerance && remainingTime > 0) {
    console.log(1); // 確保能夠輸出
  }

  // 如果已過(guò)期,返回 "已過(guò)期" 并標(biāo)記為需要重新預(yù)約
  if (remainingTime < 0) {
    return { text: '已過(guò)期', isExpired: true };
  }

  const hours = Math.floor(remainingTime / (1000 * 60 * 60));
  const minutes = Math.floor((remainingTime % (1000 * 60 * 60)) / (1000 * 60));
  const seconds = Math.floor((remainingTime % (1000 * 60)) / 1000);
  // 分時(shí)秒的格式化
  return { text: `${hours}小時(shí) ${minutes}分鐘 ${seconds}秒`, isExpired: false };
};

以上的函數(shù)需要注意的點(diǎn)如下:

由于時(shí)間的精確性和計(jì)算方式,remainingTime 很少會(huì)正好等于 0。即使時(shí)間點(diǎn)非常接近,由于毫秒級(jí)的差異,可能導(dǎo)致 remainingTime 不完全等于 0

以上就是Vue3動(dòng)態(tài)倒計(jì)時(shí)的代碼實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于Vue3動(dòng)態(tài)倒計(jì)時(shí)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue enter回車(chē)導(dǎo)致頁(yè)面刷新問(wèn)題及解決

    Vue enter回車(chē)導(dǎo)致頁(yè)面刷新問(wèn)題及解決

    這篇文章主要介紹了Vue enter回車(chē)導(dǎo)致頁(yè)面刷新問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Vue之beforeEach非登錄不能訪問(wèn)的實(shí)現(xiàn)(代碼親測(cè))

    Vue之beforeEach非登錄不能訪問(wèn)的實(shí)現(xiàn)(代碼親測(cè))

    這篇文章主要介紹了Vue之beforeEach非登錄不能訪問(wèn)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • vue使用echarts如何實(shí)現(xiàn)雙柱狀圖和雙y軸的柱狀圖

    vue使用echarts如何實(shí)現(xiàn)雙柱狀圖和雙y軸的柱狀圖

    這篇文章主要介紹了vue使用echarts如何實(shí)現(xiàn)雙柱狀圖和雙y軸的柱狀圖問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Vue3實(shí)現(xiàn)動(dòng)態(tài)路由與手動(dòng)導(dǎo)航

    Vue3實(shí)現(xiàn)動(dòng)態(tài)路由與手動(dòng)導(dǎo)航

    這篇文章主要為大家詳細(xì)介紹了如何在?Vue?3?中實(shí)現(xiàn)動(dòng)態(tài)路由注冊(cè)和手動(dòng)導(dǎo)航,確保用戶訪問(wèn)的頁(yè)面與權(quán)限對(duì)應(yīng),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12
  • Vue的diff算法原理你真的了解嗎

    Vue的diff算法原理你真的了解嗎

    這篇文章主要為大家詳細(xì)介紹了Vue的diff算法原理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • 基于腳手架創(chuàng)建Vue項(xiàng)目實(shí)現(xiàn)步驟詳解

    基于腳手架創(chuàng)建Vue項(xiàng)目實(shí)現(xiàn)步驟詳解

    這篇文章主要介紹了基于腳手架創(chuàng)建Vue項(xiàng)目實(shí)現(xiàn)步驟詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • rem實(shí)現(xiàn)響應(yīng)式布局的思路詳解

    rem實(shí)現(xiàn)響應(yīng)式布局的思路詳解

    這篇文章主要為大家介紹了rem實(shí)現(xiàn)響應(yīng)式布局的思路詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • vite+vue3使用@路徑報(bào)錯(cuò)處理

    vite+vue3使用@路徑報(bào)錯(cuò)處理

    本文主要介紹了vite+vue3使用@路徑報(bào)錯(cuò)處理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-11-11
  • vue3.0父子傳參,子修改父數(shù)據(jù)的實(shí)現(xiàn)

    vue3.0父子傳參,子修改父數(shù)據(jù)的實(shí)現(xiàn)

    這篇文章主要介紹了vue3.0父子傳參,子修改父數(shù)據(jù)的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue中如何獲取本地IP地址

    vue中如何獲取本地IP地址

    這篇文章主要介紹了vue中如何獲取本地IP地址,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04

最新評(píng)論

马关县| 蕲春县| 炎陵县| 密山市| 辽阳市| 和静县| 丰原市| 南郑县| 达日县| 炎陵县| 鄂伦春自治旗| 栾城县| 应城市| 嘉善县| 六枝特区| 沅江市| 将乐县| 隆安县| 嘉峪关市| 柳林县| 永平县| 乡城县| 宣威市| 丁青县| 宜良县| 保靖县| 济阳县| 高要市| 兖州市| 中江县| 阳新县| 南安市| 津南区| 万全县| 深州市| 龙州县| 阳泉市| 陇南市| 武宁县| 富民县| 芷江|