<template> <div> <el-tabs type="border-card"> <el-tab-pane label="秒" v-if="shouldHide('second')"> <CrontabSecond @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronsecond" /> </el-tab-pane> <el-tab-pane label="分钟" v-if="shouldHide('min')"> <CrontabMin @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronmin" /> </el-tab-pane> <el-tab-pane label="小时" v-if="shouldHide('hour')"> <CrontabHour @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronhour" /> </el-tab-pane> <el-tab-pane label="日" v-if="shouldHide('day')"> <CrontabDay @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronday" /> </el-tab-pane> <el-tab-pane label="月" v-if="shouldHide('month')"> <CrontabMonth @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronmonth" /> </el-tab-pane> <el-tab-pane label="周" v-if="shouldHide('week')"> <CrontabWeek @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronweek" /> </el-tab-pane> <el-tab-pane label="年" v-if="shouldHide('year')"> <CrontabYear @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronyear" /> </el-tab-pane> </el-tabs> <div class="popup-main"> <div class="popup-result"> <p class="title">时间表达式</p> <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> </div> <CrontabResult :ex="crontabValueString"></CrontabResult> <div class="pop_btn"> <el-button size="small" type="primary" @click="submitFill">确定</el-button> <el-button size="small" type="warning" @click="clearCron">重置</el-button> <el-button size="small" @click="hidePopup">取消</el-button> </div> </div> </div> </template> <script> import CrontabSecond from "./second.vue"; import CrontabMin from "./min.vue"; import CrontabHour from "./hour.vue"; import CrontabDay from "./day.vue"; import CrontabMonth from "./month.vue"; import CrontabWeek from "./week.vue"; import CrontabYear from "./year.vue"; import CrontabResult from "./result.vue"; export default { data() { return { tabTitles: ["秒", "分钟", "小时", "日", "月", "周", "年"], tabActive: 0, myindex: 0, crontabValueObj: { second: "*", min: "*", hour: "*", day: "*", month: "*", week: "?", year: "", }, }; }, name: "vcrontab", props: ["expression", "hideComponent"], methods: { shouldHide(key) { if (this.hideComponent && this.hideComponent.includes(key)) return false; return true; }, resolveExp() { // 反解析 表达式 if (this.expression) { let arr = this.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] : "", }; this.crontabValueObj = { ...obj, }; for (let i in obj) { if (obj[i]) this.changeRadio(i, obj[i]); } } } else { // 没有传入的表达式 则还原 this.clearCron(); } }, // tab切换值 tabCheck(index) { this.tabActive = index; }, // 由子组件触发,更改表达式组成的字段值 updateCrontabValue(name, value, from) { "updateCrontabValue", name, value, from; this.crontabValueObj[name] = value; if (from && from !== name) { console.log(`来自组件 ${from} 改变了 ${name} ${value}`); this.changeRadio(name, value); } }, // 赋值到组件 changeRadio(name, value) { let arr = ["second", "min", "hour", "month"], refName = "cron" + name, insValue; if (!this.$refs[refName]) return; if (arr.includes(name)) { if (value === "*") { insValue = 1; } else if (value.indexOf("-") > -1) { let indexArr = value.split("-"); isNaN(indexArr[0]) ? (this.$refs[refName].cycle01 = 0) : (this.$refs[refName].cycle01 = indexArr[0]); this.$refs[refName].cycle02 = indexArr[1]; insValue = 2; } else if (value.indexOf("/") > -1) { let indexArr = value.split("/"); isNaN(indexArr[0]) ? (this.$refs[refName].average01 = 0) : (this.$refs[refName].average01 = indexArr[0]); this.$refs[refName].average02 = indexArr[1]; insValue = 3; } else { insValue = 4; this.$refs[refName].checkboxList = value.split(","); } } 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]) ? (this.$refs[refName].cycle01 = 0) : (this.$refs[refName].cycle01 = indexArr[0]); this.$refs[refName].cycle02 = indexArr[1]; insValue = 3; } else if (value.indexOf("/") > -1) { let indexArr = value.split("/"); isNaN(indexArr[0]) ? (this.$refs[refName].average01 = 0) : (this.$refs[refName].average01 = indexArr[0]); this.$refs[refName].average02 = indexArr[1]; insValue = 4; } else if (value.indexOf("W") > -1) { let indexArr = value.split("W"); isNaN(indexArr[0]) ? (this.$refs[refName].workday = 0) : (this.$refs[refName].workday = indexArr[0]); insValue = 5; } else if (value === "L") { insValue = 6; } else { this.$refs[refName].checkboxList = value.split(","); 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]) ? (this.$refs[refName].cycle01 = 0) : (this.$refs[refName].cycle01 = indexArr[0]); this.$refs[refName].cycle02 = indexArr[1]; insValue = 3; } else if (value.indexOf("#") > -1) { let indexArr = value.split("#"); isNaN(indexArr[0]) ? (this.$refs[refName].average01 = 1) : (this.$refs[refName].average01 = indexArr[0]); this.$refs[refName].average02 = indexArr[1]; insValue = 4; } else if (value.indexOf("L") > -1) { let indexArr = value.split("L"); isNaN(indexArr[0]) ? (this.$refs[refName].weekday = 1) : (this.$refs[refName].weekday = indexArr[0]); insValue = 5; } else { this.$refs[refName].checkboxList = value.split(","); 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 { this.$refs[refName].checkboxList = value.split(","); insValue = 5; } } this.$refs[refName].radioValue = insValue; }, // 表单选项的子组件校验数字格式(通过-props传递) checkNumber(value, minLimit, maxLimit) { // 检查必须为整数 value = Math.floor(value); if (value < minLimit) { value = minLimit; } else if (value > maxLimit) { value = maxLimit; } return value; }, // 隐藏弹窗 hidePopup() { this.$emit("hide"); }, // 填充表达式 submitFill() { this.$emit("fill", this.crontabValueString); this.hidePopup(); }, clearCron() { // 还原选择项 ("准备还原"); this.crontabValueObj = { second: "*", min: "*", hour: "*", day: "*", month: "*", week: "?", year: "", }; for (let j in this.crontabValueObj) { this.changeRadio(j, this.crontabValueObj[j]); } }, }, computed: { crontabValueString: function() { let obj = this.crontabValueObj; let str = obj.second + " " + obj.min + " " + obj.hour + " " + obj.day + " " + obj.month + " " + obj.week + (obj.year == "" ? "" : " " + obj.year); return str; }, }, components: { CrontabSecond, CrontabMin, CrontabHour, CrontabDay, CrontabMonth, CrontabWeek, CrontabYear, CrontabResult, }, watch: { expression: "resolveExp", hideComponent(value) { // 隐藏部分组件 }, }, mounted: function() { this.resolveExp(); }, }; </script> <style scoped> .pop_btn { text-align: center; margin-top: 20px; } .popup-main { position: relative; margin: 10px auto; background: #fff; border-radius: 5px; font-size: 12px; overflow: hidden; } .popup-title { overflow: hidden; line-height: 34px; padding-top: 6px; background: #f2f2f2; } .popup-result { box-sizing: border-box; line-height: 24px; margin: 25px auto; padding: 15px 10px 10px; border: 1px solid #ccc; position: relative; } .popup-result .title { position: absolute; top: -28px; left: 50%; width: 140px; font-size: 14px; margin-left: -70px; text-align: center; line-height: 30px; background: #fff; } .popup-result table { text-align: center; width: 100%; margin: 0 auto; } .popup-result table span { display: block; width: 100%; font-family: arial; line-height: 30px; height: 30px; white-space: nowrap; overflow: hidden; border: 1px solid #e8e8e8; } .popup-result-scroll { font-size: 12px; line-height: 24px; height: 10em; overflow-y: auto; } </style>