先看最终效果
实现过程:
第一想法肯定是百度/google一下看有没有可以白嫖的
理论上,这种功能应该是比较通用的功能,信心满满的开始百度/google了,确实有不少可以用的组件
vue-cron
vcrontab
等等
界面差不多都长这样
从界面上看确实很高级,好像可以满足很多复杂的场景,不过问题在于,如果让一个不懂技术的普通用户去用,这怎么能搞明白,还不得天天找客服或是干脆放弃,So, 又努力找了找看有没有简单一点的,最终还真找到了,一个长这样的
看着跟我想要的效果很接近了,再次满怀信心的各种试,最后发现
- 样式不好定义
- 生成的cron表达式不太对
最后没办法,只能放弃了,选择自已开发
经过两三个小时的折腾,搞出来了,代码如下
Scheduler.Vue
<template>
<div>
<div class="flex flex-wrap gap-4 items-center">
<el-select v-model="selectedLevel" @change="handleLevelChange" style="width:80px;">
<el-option value="day" label="每天">每天</el-option>
<el-option value="week" label="每周">每周</el-option>
<el-option value="month" label="每月">每月</el-option>
<el-option value="year" label="每年">每年</el-option>
</el-select>
<el-select v-model="selectedMonth" @change="handleSelectChange" v-if="selectedLevel == 'year'" style="width:90px;">
<!--添加1-12月-->
<el-option v-for="month in 12" :key="month" :value="month" :label="month + '月'">{{ month }}月</el-option>
<!-- Add more months here -->
</el-select>
<el-select
v-model="selectedDate" @change="handleSelectChange"
v-if="selectedLevel == 'month' || selectedLevel == 'year'" style="width:90px;">
<!--1-31-->
<el-option v-for="date in 31" :key="date" :value="date" :label="date + '日'">{{ date }}日</el-option>
<!-- Add options for selecting date -->
</el-select>
<el-select
v-model="selectedDayofWeek" @change="handleSelectChange" v-if="selectedLevel == 'week'"
style="width:120px;">
<el-option value="2" label="星期一">星期一</el-option>
<el-option value="3" label="星期二">星期二</el-option>
<el-option value="4" label="星期三">星期三</el-option>
<el-option value="5" label="星期四">星期四</el-option>
<el-option value="6" label="星期五">星期五</el-option>
<el-option value="7" label="星期六">星期六</el-option>
<el-option value="1" label="星期日">星期日</el-option>
</el-select>
<el-select v-model="selectedHour" @change="handleSelectChange" style="width:90px;">
<el-option v-for="hour in 24" :key="hour" :value="hour" :label="hour + '时'">{{ hour }}时</el-option>
<!-- Add options for selecting hour -->
</el-select>
<el-select v-model="selectedMinutes" @change="handleSelectChange" filterable style="width:90px;">
<!-- Add options for selecting minutes -->
<el-option v-for="minute in 60" :key="minute" :value="minute" :label="minute + '分'">{{ minute }}分</el-option>
</el-select>
</div>
<div v-if="debug==true">
<p>Natural Language Description: {{ desc }}</p>
<p>Cron Expression: {{ cron }}</p>
</div>
</div>
</template>
<script>
export default {
// 组件的props
props: {
modelValue: {
type: Object,
required: true,
},
// 是否显示调试信息,true时会显示cron表达式和自然语言描述
debug: {
type: Boolean,
default: false,
},
},
// 向父组件传递数据
emits: ['update:modelValue'],
data() {
return {
selectedLevel: 'day',
selectedMonth: '',
selectedDate: '',
selectedHour: '',
selectedMinutes: '',
desc: '',
cron: '',
json:{},
levelMap: {
day: '每天',
week: '每周',
month: '每月',
year: '每年',
},
dayofWeekMap: {
2: '星期一',
3: '星期二',
4: '星期三',
5: '星期四',
6: '星期五',
7: '星期六',
8: '星期日',
},
};
},
methods: {
handleLevelChange() {
// Implement logic to update other options based on the selected level
//清除其他选项
this.selectedMonth = '';
this.selectedDate = '';
this.selectedDayofWeek = '';
this.selectedHour = '';
this.selectedMinutes = '';
this.desc = '';
this.cron = '';
this.json = {};
//根据选项设置默认值
// 更新modelValue
const valueObj = {
desc: this.desc,
cron: this.cron,
json: this.json,
};
this.$emit('update:modelValue', valueObj);
},
// 处理下拉框选择事件
handleSelectChange() {
// Implement logic to update other options based on the selected lev
switch (this.selectedLevel) {
case 'year':
this.desc = `每年${this.selectedMonth}月${this.selectedDate}日${this.selectedHour}时${this.selectedMinutes}分`;
this.json = {
level: 'year',
month: this.selectedMonth,
day: this.selectedDate,
hour: this.selectedHour,
minute: this.selectedMinutes,
};
this.cron = `0 ${this.selectedMinutes} ${this.selectedHour} ${this.selectedDate} ${this.selectedMonth} ?`;
break;
case 'month':
this.desc = `每月${this.selectedDate}日${this.selectedHour}时${this.selectedMinutes}分`;
this.json = {
level: 'month',
day: this.selectedDate,
hour: this.selectedHour,
minute: this.selectedMinutes,
};
this.cron = `0 ${this.selectedMinutes} ${this.selectedHour} ${this.selectedDate} * ?`;
break;
case 'week':
this.desc = `每周${this.dayofWeekMap[this.selectedDayofWeek]}${this.selectedHour}时${this.selectedMinutes}分`;
this.json = {
level: 'week',
dayOfWeek: this.selectedDayofWeek,
hour: this.selectedHour,
minute: this.selectedMinutes,
};
this.cron = `0 ${this.selectedMinutes} ${this.selectedHour} ? * ${this.selectedDayofWeek}`;
break;
case 'day':
this.desc = `每天${this.selectedHour}时${this.selectedMinutes}分`;
this.json = {
level: 'day',
hour: this.selectedHour,
minute: this.selectedMinutes,
};
this.cron = `0 ${this.selectedMinutes} ${this.selectedHour} * * ?`;
break;
}
const valueObj = {
desc: this.desc,
cron: this.cron,
json: this.json,
};
this.$emit('update:modelValue', valueObj);
},
},
};
</script>
<style scoped>/* Add your component styles here */</style>
使用方法也很简单,直接费用即可
//引入Scheduler组件
import Schduler from '@/components/Scheduler.vue'
//页面中使用
<Scheduler v-model="formData.scheduler" :debug="false" />
v-model绑定的是一个对象
{
desc:"",//自然语言描述
cron:"",//cron表达式
json:"",//json表达式
}
使用的时候可以如下方式
<p class="text-lightest pt-2">cron expression: {{formData.scheduler.cron}}</p>
<p class="text-lightest pt-2">cron desc: {{formData.scheduler.desc}}</p>
完成