网上找的没有满意的,决定从若依前后端分离其前端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>
标签:indexArr,refs,refName,value,Crontab,vue3,组件,setData,proxy From: https://www.cnblogs.com/Vrapile/p/18118548