vue3弹窗中循环生成表单的校验和重置问题

35 篇文章 1 订阅
29 篇文章 0 订阅

应用场景:

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>

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3,要清除表单校验,可以使用clearValidate()方法。该方法可以移除表单项的校验结果。如果不传入参数,则会移除整个表单校验结果。如果需要清除某个表单项的校验结果,可以传入该表单项的prop属性或者prop组成的数组作为参数。例如,清除手机号表单项的验证提示信息可以使用以下代码: ```javascript this.$nextTick(() => { this.$refs.form.clearValidate(\['phone'\]); }); ``` 需要注意的是,使用clearValidate()方法清除某个表单项的提示信息时,需要确保安装的Element UI版本是2.4.3及后续版本,因为这个功能是在Element UI^2.4.3版本引入的。另外,如果需要对整个表单进行重置,包括将所有字段值重置为空并移除校验结果,可以使用resetFields()方法。该方法可以对整个表单进行重置。例如,对绑定到Form组件上的属性ref为form的表单进行重置可以使用以下代码: ```javascript this.$nextTick(() => { this.$refs.form.resetFields(); }); ``` 这样就可以清除表单校验结果和字段值了。 #### 引用[.reference_title] - *1* *2* *3* [Vue 清除Form表单校验信息 清除表单验证上次提示信息](https://blog.csdn.net/weixin_49098968/article/details/129159791)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值