VUE3 v-show 引起的表单验证问题

<el-form ref="formRef" :rules="rules" :model="form" label-width="80px">

    <el-form-item label="任务类型" prop="TaskType">
        <el-radio-group v-model="form.TaskType" @change="handleChangeTaskType($event)">
              <el-radio :label="1">1</el-radio>
              <el-radio :label="2">2</el-radio>
              <el-radio :label="3">3</el-radio>
        </el-radio-group>
    </el-form-item>

    <el-form-item label="类型1要求输入内容" v-show="form.TaskType === 1" prop="TaskAttendResources">
            <!-类型1要求输入内容-->
    </el-form-item>

    <el-form-item label="类型2要求输入内容" v-show="form.TaskType === 2" prop="TaskAttendProblems">
            <!-类型2要求输入内容-->
    </el-form-item>

    <el-form-item label="类型3要求输入内容" v-show="form.TaskType === 3" prop="TaskContent">
        <QuillEditor ref="ref_QE_Content" theme="snow" :toolbar="toolbarOptions" contentType="html" enable v-model:content="form.TaskContent" placeholder="输入任务内容……" 
              @blur="onEditorBlur($event, 'TaskContent')" 
              @focus="onEditorFocus($event)"                 
              @ready="onEditorReady($event)" 
              @textChange="onTextChange($event, 'TaskContent')"
              @update:content="onContentChange($event, 'TaskContent')"
        />
    </el-form-item>

    <el-form-item>
        <el-button type="primary" @click="onSubmit">确定</el-button>
        <el-button @click="onReset">取消</el-button>
    </el-form-item>

</el-form>

如上:有一个表单,要求用户在选择“任务类型3”时,必须“TaskContent”的内容,选择类型1或类型2时则不做验证要求。

<script setup name="addtask">
    
    const form = reactive({  
      TaskType: 1,   
      TaskContent: ""   
    });
    
    const rules = {
      TaskContent: [
        { required: true, message: "请输入任务内容", trigger: ['blur', 'change'] }
      ]
    };

</script>

上述验证代码,会发现有问题,如果用户选择或者切换到了“类型1”或者“类型2”,同样会对类型3下的TaskContent进行验证,提示用户“请输入任务内容

解决方法:有人提出了把v-show 也成v-if,表单验证好像没问题了,但是程序如果进行了对TaskContent进行了其它操作,会引起不必要的错误。

最终解决方法:自定义验证规则

<script setup name="addtask">
    
    const form = reactive({  
      TaskType: 1,   
      TaskContent: ""   
    });
    
    const rules = {
      TaskContent: [
        {
          required: true,
          // message: "请输入任务内容",
          // 自定义验证,当选择类型3时,才进行TaskContent验证Value是否为空
          validator: (rule, value, callback) => {          
              const checkValue = quill_content.getText().replace(/^\s+/g, '') != ''
              if (form.TaskType === 3 && !checkValue) {
                  callback(new Error('请输入任务内容'));
              }
              else {
                  callback();
              }
          },
          trigger: ['blur', 'change']
        },
      ],
    };

</script>

Vue + Element UI 中,当使用 `v-show` 控制表单元素显示隐藏,即便表单元素可见,它仍然可能会参与校验。以下是几种解决办法: ### 动态绑定 `rules` 属性 可以根据 `v-show` 的条件动态绑定表单元素的 `rules` 属性。当元素隐藏,将 `rules` 设为空数组,这样在隐藏状态下就会进行校验。 ```vue <template> <el-form :model="form" ref="formRef"> <el-form-item label="姓名" :rules="showName ? [ { required: true, message: &#39;请输入姓名&#39;, trigger: &#39;blur&#39; } ] : []"> <el-input v-model="form.name" v-show="showName"></el-input> </el-form-item> <el-button @click="submitForm">提交</el-button> </el-form> </template> <script lang="ts" setup> import { ref } from &#39;vue&#39;; const formRef = ref(null); const form = ref({ name: &#39;&#39; }); const showName = ref(true); const submitForm = () => { formRef.value.validate((valid) => { if (valid) { console.log(&#39;表单验证通过&#39;); } else { console.log(&#39;表单验证失败&#39;); } }); }; </script> ``` ### 手动控制校验 在提交表单,手动判断哪些元素是可见的,只对可见元素进行校验。 ```vue <template> <el-form :model="form" ref="formRef"> <el-form-item label="姓名" prop="name"> <el-input v-model="form.name" v-show="showName"></el-input> </el-form-item> <el-button @click="submitForm">提交</el-button> </el-form> </template> <script lang="ts" setup> import { ref } from &#39;vue&#39;; const formRef = ref(null); const form = ref({ name: &#39;&#39; }); const showName = ref(true); const submitForm = () => { const visibleFields = []; if (showName.value) { visibleFields.push(&#39;name&#39;); } formRef.value.validateFields(visibleFields, (valid) => { if (valid) { console.log(&#39;表单验证通过&#39;); } else { console.log(&#39;表单验证失败&#39;); } }); }; </script> ``` ### 使用 `v-if` 替代 `v-show` `v-if` 是真正的条件渲染,当条件为 `false` ,元素会被从 DOM 中移除,因此会参与校验。但需要注意 `v-if` 会有更高的切换开销。 ```vue <template> <el-form :model="form" ref="formRef"> <el-form-item label="姓名" :rules="[{ required: true, message: &#39;请输入姓名&#39;, trigger: &#39;blur&#39; }]"> <el-input v-model="form.name" v-if="showName"></el-input> </el-form-item> <el-button @click="submitForm">提交</el-button> </el-form> </template> <script lang="ts" setup> import { ref } from &#39;vue&#39;; const formRef = ref(null); const form = ref({ name: &#39;&#39; }); const showName = ref(true); const submitForm = () => { formRef.value.validate((valid) => { if (valid) { console.log(&#39;表单验证通过&#39;); } else { console.log(&#39;表单验证失败&#39;); } }); }; </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JackieZhengChina

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值