应用场景:
1、弹框里的表单是根据后台返回的时段生成的,后台返回几个时段,就渲染几组表单。
-1- 重置:遍历每个表单,获取当前表单的引用,在resetFields()
-2- 校验:创建一个数组来存储每个表单的校验结果,遍历每个表单,获取当前表单的引用,校验当前表单,将校验结果存储到数组中,判断到最后一个表单的时候,检查所有的校验结果,校验通过,执行提交操作,否则,执行失败操作。
2、hour 和 hourSupHeat 不可编辑,需计算 hourSupHeat = hour * supHeat,
这里需要监听 initFormdata的变化,再循环item,再监听每个item里的supHeat,然后计算结果,我这里需要的结果是字符串形式,所以转了String。
3、表单限制只能输入数字,限制2位或3位小数,rules规则里使用正则表达式匹配,hourSupHeat 鼠标移入有公式提示,el-tooltip,使用 label 插槽把 icon 放到文字后面。
数据结构:数组对象形式
initFormData:[ { start: '9', end: '16', supTemp: '', supPres: '', hour: '8', supHeat: '', supFlow: '', hourSupHeat: '' }, { start: '16', end: '9', supTemp: '', supPres: '', hour: '16', supHeat: '', supFlow: '', hourSupHeat: '' }, ]
效果显示:
<template>
<PatrolDialog :show="show" @close="show = false" @define="save(ruleFormRef)" @cancel="cancel(ruleFormRef)" beforeClose
@handleBeforeClose="handleBeforeClose(ruleFormRef)" width="600px" top="10vh">
<template #title>
<div class="dialog-title"><img :src="weatherStationIcon" />{{ title }}</div>
</template>
<div class="formPart">
<div class="item" v-for="(item, index) in initFormData" :key="index">
<div class="time" style="padding-bottom: var(--base-padding); color: var(--gdky-primary-color);"> [{{ item.start
}}时-{{ item.end }}时]
</div>
<el-form ref="ruleFormRef" :model="item" :rules="rules" label-position="top">
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="供温 ℃" prop="supTemp">
<el-input v-model="item.supTemp" style="width:100%" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="供压 MPa" prop="supPres">
<el-input v-model="item.supPres" style="width:100%" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="时段 h" prop="hour">
<el-input v-model="item.hour" disabled style="width:100%" placeholder="请输入" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="供热 GJ/h" prop="supHeat">
<el-input v-model="item.supHeat" style="width:100%" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="供流 t/h" prop="supFlow">
<el-input v-model="item.supFlow" style="width:100%" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-tooltip class="box-item" effect="dark" content="应供热量*时间段小时数" placement="top">
<el-form-item prop="hourSupHeat">
<template #label>
<div>
<span>时段供热 GJ</span>
<i class="iconfont icon-xiangqing1" style="font-size: 14px; padding-left: 5px;"></i>
</div>
</template>
<el-input v-model="item.hourSupHeat" disabled style="width:100%" placeholder="请输入" />
</el-form-item>
</el-tooltip>
</el-col>
</el-row>
</el-form>
<div style="border-bottom:2px dashed rgba(215, 215, 215, 0.4);margin-bottom: 16px;"></div>
</div>
</div>
</PatrolDialog>
</template>
<script>
import { reactive, toRefs, computed, watch, ref, onMounted } from 'vue'
import PatrolDialog from '@/views/Components/PatrolDialog.vue'
import weatherStationIcon from '@/assets/imgs/title_img.png'
import { ElMessage } from 'element-plus'
import { debounce } from 'lodash-es'
import { getUpdateTimeDataList } from '@/api/PlatTool/CustomModules/HeatSourceDispatch/index'
const initFormData = ref([
{ start: '9', end: '16', supTemp: '', supPres: '', hour: '8', supHeat: '', supFlow: '', hourSupHeat: '' },
{ start: '16', end: '9', supTemp: '', supPres: '', hour: '16', supHeat: '', supFlow: '', hourSupHeat: '' },
])
const ruleFormRef = ref([])
export default {
components: {
PatrolDialog
},
setup(_, { emit }) {
const state = reactive({
show: false,
weatherStationIcon, // icon
title: '',
curRow: null,
rules: {
supTemp: [
{ required: true, message: '请输入数字', trigger: 'blur' },
{
pattern: /^\d+(\.\d{0,2})?$/,
message: '请输入数字,最多保留两位小数',
trigger: 'blur',
},
],
supPres: [
{ required: true, message: '请输入数字', trigger: 'blur' },
{
pattern: /^\d+(\.\d{0,3})?$/,
message: '请输入数字,最多保留三位小数',
trigger: 'blur',
},
],
supHeat: [
{ required: true, message: '请输入数字', trigger: 'blur' },
{
pattern: /^\d+(\.\d{0,2})?$/,
message: '请输入数字,最多保留两位小数',
trigger: 'blur',
},
],
supFlow: [
{ required: true, message: '请输入数字', trigger: 'blur' },
{
pattern: /^\d+(\.\d{0,2})?$/,
message: '请输入数字,最多保留两位小数',
trigger: 'blur',
},
],
},
})
const methods = {
// 打开弹窗
async open(curRow) {
state.show = true;
state.curRow = curRow;
state.title = `修改表单数据[${curRow.outletName}]`
// 设置选项
initFormData.value = curRow.timeDataList
// initFormData = [
// { start: '9', end: '12', supTemp: '45', supPres: '12', hour: '11', supHeat: '2', supFlow: '7', hourSupHeat: '22' },
// { start: '15', end: '18', supTemp: '66', supPres: '36', hour: '2', supHeat: '10', supFlow: '5', hourSupHeat: '20' },
// { start: '18', end: '23', supTemp: '89', supPres: '65', hour: '3', supHeat: '33', supFlow: '6', hourSupHeat: '99' },
// { start: '23', end: '9', supTemp: '36', supPres: '55', hour: '4', supHeat: '1', supFlow: '3', hourSupHeat: '4' }
// ]
},
// 保存
save(ruleFormRef) {
// 创建一个数组来存储每个表单的校验结果
const formValidationResults = [];
// 循环遍历每个表单
for (let i = 0; i < ruleFormRef.length; i++) {
// 获取当前表单的引用
const formRef = ruleFormRef[i];
// 校验当前表单
formRef.validate((valid) => {
// 将校验结果存储到数组中
formValidationResults[i] = valid;
if (i === ruleFormRef.length - 1) {
const allFormsValid = formValidationResults.every((result) => result);
if (allFormsValid) {
// 执行提交操作
methods.submitForms();
} else {
console.log('error submit!')
ElMessage.error('修改失败')
}
}
});
}
},
submitForms() {
let data = {
outletId: state.curRow.outletId,
getTime: state.curRow.getTime,
timeDataList: initFormData.value
}
getUpdateTimeDataList(data).then(res => {
if (res.code == '0') {
ElMessage.success('修改成功');
// 刷新表格数据
emit('saveSuccess');
state.show = false;
} else {
ElMessage.error(`修改失败:${res?.msg}`);
}
}).catch(err => {
console.log(err)
ElMessage.error('修改失败')
})
},
// 重置
cancel(formEl) {
if (!formEl) return
// 循环遍历每个表单
for (let i = 0; i < formEl.length; i++) {
// 获取当前表单的引用
const formRef = formEl[i];
formRef.resetFields()
}
},
handleBeforeClose(formEl) {
if (!formEl) return
// 循环遍历每个表单
for (let i = 0; i < formEl.length; i++) {
// 获取当前表单的引用
const formRef = formEl[i];
formRef.resetFields()
}
state.show = false
},
}
watch(
initFormData,
debounce((newVal, oldVal) => {
newVal.forEach(item => {
// 监听item.supHeat的变化
watch(() => item.supHeat, (newVal, oldVal) => {
// 更新item.hourSupHeat的值
item.hourSupHeat = String(item.supHeat * item.hour);
});
});
}, 300),
{ deep: true }
);
onMounted(() => {
})
return {
...toRefs(state),
...methods,
initFormData,
ruleFormRef
}
}
}
</script>
<style lang='less' scoped>
.dialog-title {
display: flex;
font-size: 16px;
font-family: MicrosoftYaHeiSemibold;
color: var(--gdky-main-content-color);
line-height: 24px;
padding-bottom: var(--base-padding);
img {
margin-right: 8px;
}
}
.formPart {
display: flex;
flex-direction: column;
justify-content: center;
overflow: hidden;
}
</style>