vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue3的定时器cron组件

vue3的定时器cron组件详解

作者:不想长胖的可乐鸭

该文章介绍了如何在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 * * *"

总结

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

您可能感兴趣的文章:
阅读全文