vue3的定时器cron组件详解

 更新时间:2025年10月25日 11:33:28   作者:不想长胖的可乐鸭  
该文章介绍了如何在Vue3和Antd-Vue中实现一个定时任务调度组件,该组件支持每日定时任务,并返回cron格式的字符串,父组件调用该组件后,会得到一个cron格式的时间字符串,表示任务的执行时间,例如,“000009***”表示每天的9点

先看图

仅适用于vue3+antd-vue,仅对业务需求,每日定时。

实现功能如下:

话不多说,上组件代码

组件代码如下,如需改动,找ai就完事

<!-- src/components/CronEditor.vue -->
<template>
  <div class="cron-editor">
    <a-form-item label="推送频率" :labelCol="{ span: 4 }">
      <a-radio-group v-model:value="cronType" @change="onTypeChange">
        <a-radio value="daily">每天</a-radio>
        <a-radio value="weekly">每周</a-radio>
      </a-radio-group>
    </a-form-item>

    <a-form-item v-if="cronType === 'daily'" label="推送时间" :labelCol="{ span: 4 }">
      <a-time-picker
        :value="dailyTime"
        format="HH:mm"
        value-format="HH:mm"
        @change="onDailyTimeChange"
      />
    </a-form-item>

    <template v-if="cronType === 'weekly'">
      <a-form-item label="选择星期" :labelCol="{ span: 4 }">
        <a-checkbox-group v-model:value="selectedWeekdays" @change="onWeekdaysChange">
          <a-checkbox v-for="day in weekdays" :key="day.value" :value="day.value">
            {{ day.label }}
          </a-checkbox>
        </a-checkbox-group>
      </a-form-item>

      <a-form-item label="推送时间" :labelCol="{ span: 4 }">
        <a-time-picker
          :value="weeklyTime"
          format="HH:mm"
          value-format="HH:mm"
          @change="onWeeklyTimeChange"
        />
      </a-form-item>
    </template>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'

const props = defineProps<{
  modelValue?: string
}>()

const emit = defineEmits<{(e: 'update:modelValue', value: string): void}>()

// Cron 类型:每天或每周
const cronType = ref<'daily' | 'weekly'>('daily')

// 每天推送的时间
const dailyTime = ref<string>('09:00')

// 每周推送的星期选择
const selectedWeekdays = ref<number[]>([1]) // 默认周一

// 每周推送的时间
const weeklyTime = ref<string>('09:00')

// 星期选项
const weekdays = [
  { value: 1, label: '周一' },
  { value: 2, label: '周二' },
  { value: 3, label: '周三' },
  { value: 4, label: '周四' },
  { value: 5, label: '周五' },
  { value: 6, label: '周六' },
  { value: 7, label: '周日' }
]

// 当类型改变时重置时间
const onTypeChange = () => {
  if (cronType.value === 'daily') {
    generateDailyCron()
  } else {
    generateWeeklyCron()
  }
}

// 处理每天时间变化
const onDailyTimeChange = (time: string | string[], timeString: string) => {
  dailyTime.value = timeString
  generateDailyCron()
}

// 处理每周时间变化
const onWeeklyTimeChange = (time: string | string[], timeString: string) => {
  weeklyTime.value = timeString
  generateWeeklyCron()
}

// 处理星期选择变化
const onWeekdaysChange = (values: number[]) => {
  selectedWeekdays.value = values
  generateWeeklyCron()
}

// 生成每天的 cron 表达式
const generateDailyCron = () => {
  const time = dailyTime.value || '09:00'
  const [hour, minute] = time.split(':')
  const cron = `00 ${minute} ${hour} * * *`
  emit('update:modelValue', cron)
}

// 生成每周的 cron 表达式
const generateWeeklyCron = () => {
  if (selectedWeekdays.value.length === 0) return

  const time = weeklyTime.value || '09:00'
  const [hour, minute] = time.split(':')

  // 如果选择了所有星期(周一到周日),则生成每天的cron表达式
  if (selectedWeekdays.value.length === 7) {
    const cron = `00 ${minute} ${hour} * * *`
    emit('update:modelValue', cron)
  } else {
    const days = selectedWeekdays.value.sort().join(',')
    const cron = `00 ${minute} ${hour} * * ${days}`
    emit('update:modelValue', cron)
  }
}

// 解析传入的 cron 表达式
const parseCronExpression = (cron: string) => {
  if (!cron) return

  const parts = cron.split(' ')
  // 现在期望接收6个部分(包含秒)而不是5个部分
  if (parts.length !== 6) return

  // 解构出秒字段,但我们在解析时忽略它
  const [second, minute, hour, dayOfMonth, month, dayOfWeek] = parts

  // 判断是每天还是每周
  if (dayOfMonth === '*' && month === '*' && dayOfWeek === '*') {
    // 每天
    // cronType.value = 'daily'
    dailyTime.value = `${hour}:${minute}`
  } else if (dayOfMonth === '*' && month === '*' && dayOfWeek !== '*') {
    // 每周
    cronType.value = 'weekly'
    weeklyTime.value = `${hour}:${minute}`
    selectedWeekdays.value = dayOfWeek.split(',').map(Number)
  }
}

// 监听 modelValue 变化
watch(() => props.modelValue, (newVal) => {
  if (newVal) {
    parseCronExpression(newVal)
  }
}, { immediate: true })

// 初始化生成 cron 表达式
generateDailyCron()
</script>

<style scoped>
.cron-editor {
  width: 100%;
}
</style>

父组件调用:

<CronEditor v-model="time" />

import CronEditor from './CronEditor.vue'

组件调用会直接回传cron格式的string类型数据。周选择选择完毕默认为每天。

例如每天的九点:"00 00 09 * * *"

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • vue自定义全局组件实现弹框案例

    vue自定义全局组件实现弹框案例

    这篇文章主要为大家详细介绍了vue自定义全局组件实现弹框案例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • 基于ElementUI实现v-tooltip指令的示例代码

    基于ElementUI实现v-tooltip指令的示例代码

    文本溢出隐藏并使用tooltip 提示的需求,相信在平时的开发中会经常遇到,常规做法一般是使用 elementui 的 el-tooltip 组件,在每次组件更新的时候去获取元素的宽度/高度判断是否被隐藏,本文给大家介绍了基于ElementUI实现v-tooltip指令,需要的朋友可以参考下
    2024-09-09
  • vue中改变了vuex数据视图不更新,也监听不到的原因及解决

    vue中改变了vuex数据视图不更新,也监听不到的原因及解决

    这篇文章主要介绍了vue中改变了vuex数据视图不更新,也监听不到的原因及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • 一文带你搞懂Vue3如何使用讯飞大模型

    一文带你搞懂Vue3如何使用讯飞大模型

    这篇文章主要为大家详细介绍了Vue3使用讯飞大模型的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-12-12
  • 手写Vue内置组件component的实现示例

    手写Vue内置组件component的实现示例

    本文主要介绍了手写Vue内置组件component的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • 解决Vue的文本编辑器 vue-quill-editor 小图标样式排布错乱问题

    解决Vue的文本编辑器 vue-quill-editor 小图标样式排布错乱问题

    这篇文章主要介绍了解决Vue的文本编辑器 vue-quill-editor 小图标样式排布错乱问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • vue-cli安装全过程(附带cnpm安装不成功及vue不是内部命令)

    vue-cli安装全过程(附带cnpm安装不成功及vue不是内部命令)

    这篇文章主要介绍了vue-cli安装全过程(附带cnpm安装不成功及vue不是内部命令),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • 浅谈VUE uni-app 常用API

    浅谈VUE uni-app 常用API

    这篇文章主要介绍了uni-app 常用API,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • Vue实现右键菜单组件的超详细教程(支持快捷键)

    Vue实现右键菜单组件的超详细教程(支持快捷键)

    右键菜单组件非常常见,所有的前端开发工程师都会遇到类似的功能组件开发需求,这篇文章主要给大家介绍了关于Vue实现右键菜单组件的超详细教程,文中介绍的方法支持快捷键,需要的朋友可以参考下
    2024-02-02
  • vue如何使用原生高德地图你知道吗

    vue如何使用原生高德地图你知道吗

    这篇文章主要为大家详细介绍了vue如何使用原生高德地图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02

最新评论