当前位置:首页 > VUE

vue实现倒计时

2026-01-06 23:05:01VUE

Vue 实现倒计时的基本方法

使用 setInterval 和响应式数据

在 Vue 组件中定义一个响应式变量(如 countdown),通过 setInterval 每秒更新数值。组件销毁时清除定时器避免内存泄漏。

vue实现倒计时

<template>
  <div>{{ formattedTime }}</div>
</template>

<script>
export default {
  data() {
    return {
      countdown: 60, // 初始秒数
      timer: null
    }
  },
  computed: {
    formattedTime() {
      const minutes = Math.floor(this.countdown / 60);
      const seconds = this.countdown % 60;
      return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
    }
  },
  mounted() {
    this.timer = setInterval(() => {
      if (this.countdown > 0) {
        this.countdown--;
      } else {
        clearInterval(this.timer);
      }
    }, 1000);
  },
  beforeDestroy() {
    clearInterval(this.timer);
  }
}
</script>

使用 Composition API(Vue 3)

通过 refonMounted/onUnmounted 实现更简洁的逻辑:

<template>
  <div>{{ minutes }}:{{ seconds < 10 ? '0' : '' }}{{ seconds }}</div>
</template>

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

const countdown = ref(60);
let timer = null;

const minutes = computed(() => Math.floor(countdown.value / 60));
const seconds = computed(() => countdown.value % 60);

onMounted(() => {
  timer = setInterval(() => {
    if (countdown.value > 0) {
      countdown.value--;
    } else {
      clearInterval(timer);
    }
  }, 1000);
});

onUnmounted(() => clearInterval(timer));
</script>

封装可复用的倒计时 Hook(Vue 3)

将逻辑抽离为自定义 Hook,便于多处复用:

vue实现倒计时

// useCountdown.js
import { ref, computed, onUnmounted } from 'vue';

export function useCountdown(initialTime) {
  const countdown = ref(initialTime);
  let timer = null;

  const start = () => {
    timer = setInterval(() => {
      if (countdown.value > 0) {
        countdown.value--;
      } else {
        clearInterval(timer);
      }
    }, 1000);
  };

  const minutes = computed(() => Math.floor(countdown.value / 60));
  const seconds = computed(() => countdown.value % 60);

  onUnmounted(() => clearInterval(timer));

  return { countdown, minutes, seconds, start };
}

组件中使用:

<template>
  <div>{{ minutes }}:{{ seconds < 10 ? '0' : '' }}{{ seconds }}</div>
</template>

<script setup>
import { useCountdown } from './useCountdown';

const { minutes, seconds } = useCountdown(60);
</script>

支持暂停和重置功能

扩展基础倒计时,增加控制方法:

<template>
  <div>
    <div>{{ minutes }}:{{ seconds < 10 ? '0' : '' }}{{ seconds }}</div>
    <button @click="pause">暂停</button>
    <button @click="reset">重置</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      countdown: 60,
      timer: null,
      isPaused: false
    }
  },
  methods: {
    pause() {
      this.isPaused = !this.isPaused;
      if (this.isPaused) {
        clearInterval(this.timer);
      } else {
        this.startTimer();
      }
    },
    reset() {
      clearInterval(this.timer);
      this.countdown = 60;
      this.startTimer();
    },
    startTimer() {
      this.timer = setInterval(() => {
        if (this.countdown > 0) {
          this.countdown--;
        } else {
          clearInterval(this.timer);
        }
      }, 1000);
    }
  },
  mounted() {
    this.startTimer();
  }
}
</script>

注意事项

  1. 定时器清理:务必在组件销毁时清除定时器,防止内存泄漏。
  2. 性能优化:频繁操作 DOM 时考虑使用 requestAnimationFrame
  3. 格式化显示:通过计算属性处理时间格式,保持模板简洁。
  4. 跨组件通信:如需全局倒计时,可通过 Vuex/Pinia 管理状态。

标签: 倒计时vue
分享给朋友:

相关文章

vue前端实现打印功能

vue前端实现打印功能

使用Vue实现前端打印功能 在Vue项目中实现打印功能可以通过多种方式完成,以下是几种常见的方法: 使用window.print()方法 这是最简单的打印方式,直接调用浏览器的打印功能。 meth…

vue实现slider

vue实现slider

Vue 实现 Slider 组件 使用 Vue 实现 Slider 组件可以通过原生开发或借助第三方库。以下是两种常见方法: 原生实现 Slider 创建一个基础的 Slider 组件,通过 v-m…

vue插槽实现

vue插槽实现

插槽的基本概念 Vue插槽(Slot)是一种内容分发机制,允许父组件向子组件传递模板片段,子组件通过<slot>标签定义接收位置。插槽的核心作用是增强组件的灵活性和复用性。 默认插槽 子…

分页实现vue

分页实现vue

分页实现(Vue) 在Vue中实现分页功能通常需要结合前端分页逻辑和后端API支持。以下是两种常见的实现方式: 前端分页实现 适用于数据量较小的情况,直接在客户端完成分页逻辑。 <tem…

vue实现标签

vue实现标签

Vue 实现标签的方法 在 Vue 中实现标签功能可以通过多种方式完成,以下是几种常见的方法: 使用动态组件 动态组件可以根据不同的条件渲染不同的标签内容。通过 :is 属性动态绑定组件名,实现标…

javascript实现vue

javascript实现vue

Vue.js 的基本实现 在 JavaScript 中实现 Vue.js 的核心功能,主要包括数据绑定、响应式系统和虚拟 DOM。以下是一个简化的实现示例。 数据响应式系统 通过 Object.d…