| <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> |