基于vue3的Crontab组件
网上找的没有满意的,决定从若依前后端分离其前端vue2中的crontab进行转换,先上效果
若依:


改后:


v2转v3没什么难度,其中有大量的将 this.*** 替换为 ***.value,笔者写了个正则替换,希望可以帮助大家
this.(\w+) $1.value
需要注意的有,在v2中【this.$refs[refName].cycle01 = indexArr[0]】这样写
在v3中要转换一下,在子组件中用【defineExpose】抛出一个setData方法,然后【proxy.$refs[refName].setData("cycle01", Number(indexArr[0]))】赋值
贴出核心Crontab.vue的代码,其子组件就不一一贴了,需要的可以自己下若依代码进行转换
<template>
<div class="crontab">
<el-tabs type="border-card">
<el-tab-pane label="秒">
<CrontabSecond
@update="updateCrontabValue"
v-model:check="checkNumber"
v-model:cron="crontabValueObj"
ref="cronsecond"
/>
</el-tab-pane> <el-tab-pane label="分钟">
<CrontabMin
@update="updateCrontabValue"
v-model:check="checkNumber"
v-model:cron="crontabValueObj"
ref="cronmin"
/>
</el-tab-pane> <el-tab-pane label="小时">
<CrontabHour
@update="updateCrontabValue"
v-model:check="checkNumber"
v-model:cron="crontabValueObj"
ref="cronhour"
/>
</el-tab-pane> <el-tab-pane label="日">
<CrontabDay
@update="updateCrontabValue"
v-model:check="checkNumber"
v-model:cron="crontabValueObj"
ref="cronday"
/>
</el-tab-pane> <el-tab-pane label="月">
<CrontabMonth
@update="updateCrontabValue"
v-model:check="checkNumber"
v-model:cron="crontabValueObj"
ref="cronmonth"
/>
</el-tab-pane> <el-tab-pane label="周">
<CrontabWeek
@update="updateCrontabValue"
v-model:check="checkNumber"
v-model:cron="crontabValueObj"
ref="cronweek"
/>
</el-tab-pane> <el-tab-pane label="年">
<CrontabYear
@update="updateCrontabValue"
v-model:check="checkNumber"
v-model:cron="crontabValueObj"
ref="cronyear"
/>
</el-tab-pane>
</el-tabs> <div class="crontab-main">
<div class="crontab-main-table">
<table>
<thead>
<th v-for="item of tabTitles" width="40" :key="item">{{item}}</th>
<!-- <th>Cron 表达式</th> -->
</thead>
<tbody>
<td>
<span>{{crontabValueObj.second}}</span>
</td>
<td>
<span>{{crontabValueObj.min}}</span>
</td>
<td>
<span>{{crontabValueObj.hour}}</span>
</td>
<td>
<span>{{crontabValueObj.day}}</span>
</td>
<td>
<span>{{crontabValueObj.month}}</span>
</td>
<td>
<span>{{crontabValueObj.week}}</span>
</td>
<td>
<span>{{crontabValueObj.year}}</span>
</td>
<!-- <td>
<span>{{crontabValueString}}</span>
</td> -->
</tbody>
</table>
<table>
<thead>
<th>Cron 表达式</th>
</thead>
<tbody>
<td>
<span>{{crontabValueString}}</span>
</td>
</tbody>
</table>
</div> <div class="crontab-main-result">
<CrontabResult v-model:ex="crontabValueString"></CrontabResult>
</div>
</div> </div>
</template> <script setup name="Crontab">
import CrontabSecond from "./crontab/CrontabSecond.vue";
import CrontabMin from "./crontab/CrontabMin.vue";
import CrontabHour from "./crontab/CrontabHour.vue";
import CrontabDay from "./crontab/CrontabDay.vue";
import CrontabMonth from "./crontab/CrontabMonth.vue";
import CrontabWeek from "./crontab/CrontabWeek.vue";
import CrontabYear from "./crontab/CrontabYear.vue";
import CrontabResult from "./crontab/CrontabResult.vue"; const { proxy } = getCurrentInstance(); const emits = defineEmits(["hide", "fill"]); const props = defineProps({
expression: {type: String, default: ""}
}) const tabTitles = ref(["秒", "分钟", "小时", "日", "月", "周", "年"])
const tabActive = ref(0)
const crontabValueObj = ref({
second: "*",
min: "*",
hour: "*",
day: "*",
month: "*",
week: "?",
year: "",
}) const crontabValueString = computed(() => {
let obj = crontabValueObj.value;
let str =
obj.second +
" " +
obj.min +
" " +
obj.hour +
" " +
obj.day +
" " +
obj.month +
" " +
obj.week +
(obj.year == "" ? "" : " " + obj.year);
return str;
}) onMounted(() => {
resolveExp();
}) watch(() => props.expression, (v) => {
resolveExp();
}); function resolveExp() {
// 反解析 表达式
if (props.expression) {
let arr = props.expression.split(" ");
if (arr.length >= 6) {
//6 位以上是合法表达式
let obj = {
second: arr[0],
min: arr[1],
hour: arr[2],
day: arr[3],
month: arr[4],
week: arr[5],
year: arr[6] ? arr[6] : "",
};
crontabValueObj.value = {
...obj,
};
for (let i in obj) {
if (obj[i]) changeRadio(i, obj[i]);
}
}
} else {
// 没有传入的表达式 则还原
clearCron();
}
}
// tab切换值
function tabCheck(index) {
tabActive.value = index;
}
// 由子组件触发,更改表达式组成的字段值
function updateCrontabValue(name, value, from) {
// "updateCrontabValue", name, value, from;
crontabValueObj.value[name] = value;
if (from && from !== name) {
console.log(`来自组件 ${from} 改变了 ${name} ${value}`);
changeRadio(name, value);
}
}
// 赋值到组件
function changeRadio(name, value) {
let arr = ["second", "min", "hour", "month"]
let refName = "cron" + name
let insValue; if (!proxy.$refs[refName]) return; if (arr.includes(name)) {
if (value === "*") {
insValue = 1;
} else if (value.indexOf("-") > -1) {
let indexArr = value.split("-");
isNaN(indexArr[0])
? (proxy.$refs[refName].setData("cycle01", 0))
: (proxy.$refs[refName].setData("cycle01", Number(indexArr[0])));
proxy.$refs[refName].setData("cycle02", Number(indexArr[1]));
insValue = 2;
} else if (value.indexOf("/") > -1) {
let indexArr = value.split("/");
isNaN(indexArr[0])
? (proxy.$refs[refName].setData("average01", 0))
: (proxy.$refs[refName].setData("average01", Number(indexArr[0])));
proxy.$refs[refName].setData("average02", Number(indexArr[1]));
insValue = 3;
} else {
insValue = 4;
let list = value.split(",");
for(let item of list){
item = String(item)
}
proxy.$refs[refName].setData("checkboxList", list);
}
} else if (name == "day") {
if (value === "*") {
insValue = 1;
} else if (value == "?") {
insValue = 2;
} else if (value.indexOf("-") > -1) {
let indexArr = value.split("-");
isNaN(indexArr[0])
? (proxy.$refs[refName].setData("cycle01", 0))
: (proxy.$refs[refName].setData("cycle01", Number(indexArr[0])));
proxy.$refs[refName].setData("cycle02", Number(indexArr[1]));
insValue = 3;
} else if (value.indexOf("/") > -1) {
let indexArr = value.split("/");
isNaN(indexArr[0])
? (proxy.$refs[refName].setData("average01", 0))
: (proxy.$refs[refName].setData("average01", Number(indexArr[0])));
proxy.$refs[refName].setData("average02", Number(indexArr[1]));
insValue = 4;
} else if (value.indexOf("W") > -1) {
let indexArr = value.split("W");
isNaN(indexArr[0])
? (proxy.$refs[refName].setData("workday", 0))
: (proxy.$refs[refName].setData("workday", Number(indexArr[0])));
insValue = 5;
} else if (value === "L") {
insValue = 6;
} else {
let list = value.split(",");
for(let item of list){
item = String(item)
}
proxy.$refs[refName].setData("checkboxList", list);
insValue = 7;
}
} else if (name == "week") {
if (value === "*") {
insValue = 1;
} else if (value == "?") {
insValue = 2;
} else if (value.indexOf("-") > -1) {
let indexArr = value.split("-");
isNaN(indexArr[0])
? (proxy.$refs[refName].setData("cycle01", "0"))
: (proxy.$refs[refName].setData("cycle01", String(indexArr[0])));
proxy.$refs[refName].setData("cycle02", String(indexArr[1]));
insValue = 3;
} else if (value.indexOf("#") > -1) {
let indexArr = value.split("#");
isNaN(indexArr[0])
? (proxy.$refs[refName].setData("average01", 1))
: (proxy.$refs[refName].setData("average01", Number(indexArr[0])));
proxy.$refs[refName].setData("average02", String(indexArr[1]));
insValue = 4;
} else if (value.indexOf("L") > -1) {
let indexArr = value.split("L");
isNaN(indexArr[0])
? (proxy.$refs[refName].setData("weekday", "1"))
: (proxy.$refs[refName].setData("weekday", String(indexArr[0])));
insValue = 5;
} else {
let list = value.split(",");
for(let item of list){
item = String(item)
}
proxy.$refs[refName].setData("checkboxList", list);
insValue = 6;
}
} else if (name == "year") {
if (value == "") {
insValue = 1;
} else if (value == "*") {
insValue = 2;
} else if (value.indexOf("-") > -1) {
insValue = 3;
} else if (value.indexOf("/") > -1) {
insValue = 4;
} else {
let list = value.split(",");
for(let item of list){
item = String(item)
}
proxy.$refs[refName].setData("checkboxList", list);
insValue = 5;
}
}
proxy.$refs[refName].setData("radioValue", insValue);
}
// 表单选项的子组件校验数字格式(通过-props传递)
function checkNumber(value, minLimit, maxLimit) {
// 检查必须为整数
value = Math.floor(Number(value));
if (value < minLimit) {
value = minLimit;
} else if (value > maxLimit) {
value = maxLimit;
}
return value;
}
// 隐藏弹窗
function hidePopup() {
emits("hide");
}
// 填充表达式
function submitFill() {
emits("fill", crontabValueString);
hidePopup();
}
function clearCron() {
// 还原选择项
("准备还原");
crontabValueObj.value = {
second: "*",
min: "*",
hour: "*",
day: "*",
month: "*",
week: "?",
year: "",
};
for (let j in crontabValueObj.value) {
changeRadio(j, crontabValueObj.value[j]);
}
} defineExpose({
submitFill, clearCron
})
</script>
<style scoped>
.crontab{
flex: 1;
height: 100%;
display: flex;
flex-direction: column;
}
.crontab-main {
flex: 1;
width: 100%;
margin: 10px auto;
background: #fff;
border-radius: 5px;
font-size: 12px;
border: 1px solid #ccc;
box-sizing: border-box;
line-height: 24px;
padding: 5px 10px 5px;
display: flex;
justify-content: space-between;
overflow-y: auto;
}
.crontab-main-table {
box-sizing: border-box;
line-height: 24px;
padding: 5px 10px 5px;
width: 50%;
display: flex;
flex-direction: column;
justify-content: space-around;
table {
text-align: center;
width: 100%;
margin: 0;
span {
display: block;
width: 100%;
font-family: arial;
line-height: 30px;
height: 30px;
white-space: nowrap;
overflow: hidden;
border: 1px solid #e8e8e8;
}
}
} .crontab-main-result {
box-sizing: border-box;
padding: 5px 10px 5px;
background-color: #f1f1f1;
background-size: cover;
width: 48%;
display: flex;
flex-direction: column;
.crontab-result-title{
padding: 5px;
}
:deep(.crontab-result-scroll) {
font-size: 12px;
line-height: 24px;
margin: 0 !important;
padding-left: 80px;
}
} .crontab-footer {
text-align: right;
height: 25px;
padding: 5px 20px;
}
</style>
将原来组件的按钮移到引用存,引用样例
<el-dialog title="Cron表达式生成器" v-model="formCrontabOpen" append-to-body destroy-on-close class="nine-tanchuang-001">
<!-- <crontab @change="cronChange" v-model:value="formData.cronExpression" /> -->
<Crontab ref="crontabRef" @hide="formCrontabOpen=false" @fill="crontabFill" v-model:expression="formData.cronExpression"></Crontab>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="formCrontSubmit">确 定</el-button>
<el-button type="warning" @click="formCrontReset">重 置</el-button>
<el-button @click="formCrontabOpen=false">取 消</el-button>
</div>
</template>
</el-dialog>
基于vue3的Crontab组件的更多相关文章
- vue3系列:vue3.0自定义虚拟滚动条V3Scroll|vue3模拟滚动条组件
基于Vue3.0构建PC桌面端自定义美化滚动条组件V3Scroll. 前段时间有分享一个Vue3 PC网页端弹窗组件,今天带来最新开发的Vue3.0版虚拟滚动条组件. V3Scroll 使用vue3. ...
- Vue3.x 关于组件的那些变化(新手必看篇)
一.组件内的 data 为什么总是函数形式? 我们试着先做一个计数器案例,把 data 的返回形式修改成一个对象.具体的代码如下: <template> <div> <b ...
- 为什么 Vue3.js / Element+ 组件属性前面有的需要添加冒号,有的不需要?
背景 使用 Element+ Layout 布局: <el-row> <el-col :span="12"><div class="grid ...
- 基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用
刚完成一些前端项目的开发,腾出精力来总结一些前端开发的技术点,以及继续完善基于SqlSugar的开发框架循序渐进介绍的系列文章,本篇随笔主要介绍一下基于Vue3+TypeScript的全局对象的注入和 ...
- 基于Vue3+TS的Monorepo前端项目架构设计与实现
写在前面 你好,我是前端程序员鼓励师岩家兴!去年在另一个项目https://juejin.cn/post/7121736546000044046中,我向读者朋友们介绍了结合npm包管理工具yarn作v ...
- 基于Vue3的Leaflet基础
1. 概述 Leaflet 是一个开源.轻量并且对移动端友好的交互式地图 JavaScript 库,大小仅仅只有 39 KB, 拥有绝大部分开发者所需要的所有地图特性 Leaflet 的官网为:Lea ...
- 基于PHP的crontab定时任务管理
BY JENNER · 2014年11月10日· 阅读次数:6 linux的crontab一直是server运维.业务开展的利器.但当定时任务增多时,管理和迁移都变得非常麻烦,并且easy出问题.以下 ...
- 基于vue项目的组件中导入mui框架初始化滑动等效果时需移除严格模式的问题
基于vue项目的组件中导入mui框架初始化滑动等效果时,控制台报错:Uncaught TypeError: 'caller', 'callee', and 'arguments' properties ...
- 基于log4net的日志组件扩展封装,实现自动记录交互日志 XYH.Log4Net.Extend(微服务监控)
背景: 随着公司的项目不断的完善,功能越来越复杂,服务也越来越多(微服务),公司迫切需要对整个系统的每一个程序的运行情况进行监控,并且能够实现对自动记录不同服务间的程序调用的交互日志,以及通一个服务或 ...
- 基于第三方vuejs库组件做适配性个性开发
相信大家在使用vuejs时候会用到很多的第三方库,能够找到适合自己的库并且加以使用可以大大加快进度,减少bug.但是很多时候会出现这样一个尴尬的境地: 基线的第三方组件并不能很好地满足我们自己地需求, ...
随机推荐
- java数组实现的超市管理系统(控制台)
说明:使用数组存储数据,针对用户功能1:增加用户2:删除用户3:修改用户:针对商品功能:1.显示所有商品2.修改商品信息3.添加商品信息4.删除商品信息5.查询商品信息 效果展示 ========== ...
- 【LeetCode二叉树#10】从中序与后序(或者前序)遍历序列构造二叉树(首次构造二叉树)
从中序与后序遍历序列构造二叉树 力扣题目链接(opens new window) 根据一棵树的中序遍历与后序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如,给出 中序遍历 inorde ...
- 【Azure 应用服务】App Service 部署txt静态文件和Jar包在不同目录中的解决办法
问题描述 在Web App wwwroot (Windows系统中)根目录下如何部署一个jar包和一个text文件,让两个文件都能被访问? 解决办法 Jar包和Text文件都分别放置在两个单独的文件夹 ...
- 用Pandoc生成TXT格式的目录
我一直使用Markdown格式写作,使用Pandoc生成PDF和Word格式的文档.Pandoc能生成很好的章节和目录,但有时候,也需要生成TXT格式的目录,今天就尝试了一下. 由于我写的内容章节比较 ...
- 详解Python中sys模块的功能与应用
本文分享自华为云社区<深入Python:sys模块的功能与应用详解>,作者: 柠檬味拥抱. 在Python的标准库中,sys 模块是一个常用而强大的工具,它提供了与Python解释器交互的 ...
- Word中的公式复制到Visio中乱码问题
将word中编辑好的公式复制到Visio中出现乱码问题 如图所示问题: 解决方案(Visio 选项 --> 高级 --> 显示 ->勾选禁用增强元文件优化) 具体的公式导入和解决操作 ...
- clickhouse快速上手和问题记录
clickhouse官方中文社区实战经验:手把手教你搭建单机clickhouse开发环境 我是用的是centOS7的虚拟机, 官方教程中的:sudo /etc/init.d/clickhouse-se ...
- vscode vue 鼠标Ctrl+单击 函数跳转 插件名称:vue-helper
- GO 语言的并发编程相关知识点简介与测试【GO 基础】
〇.什么是协程 Coroutines ? 进程和线程太常见,本文就不再赘述了,直接一起看下什么是协程.如下图,先看下协程的定位: 关于用户空间和内核空间:进程运行起来就涉及到对内存资源的管理,然而内存 ...
- Java基础知识篇02——Java基本语法
一.数据类型 定义: 就是用了保存数据的一个类型,一种数据类型,只能保存该类型数据值 作用: 只有了解数据类型,才能选择合适的类型存放数据,才能更好的利用计算机硬件资源(内存和硬盘等). 不同的数据类 ...