持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情
写在前面的话
本次项目使用到的是vue3.0+ts。上文中封装了form表单的基础功能,实际开发中,表单验证也是极其重要的,当然还有其他个性化开发也要完善。本文就来详细总结一下本人的开发思路。
表单验证
一般开发过程,我们表单都是在<el-form>上添加一个rules规则,然后添加一个个规则进数组中,如果这样开发的话,就是去了封装的意义。实际上我们发现在elementui文档中,每个<el-form-item>都可单独添加一个rules的规则,利用这个,我们便可以完成表单验证的功能的开发。
父组件:给配置项formData数组中给每个表单项添加一个rule规则和是否必选的required字段,和必选后会展示的信息message字段。
如下:
子组件:
- 接受每个rule规则,和是否必选的required字段,并使用v-for循环给到每个表单项
- 提交按钮时,添加表单验证,如表单验证通过,才允许提交
如下:
<el-form ref="ruleFormRef" :model="dialogForm">
<el-form-item
v-for="(item, index) in form"
:key="index"
:label="item.label"
:rules="ruleData(item)"
:prop="item.name"
>
<template v-if="item.type == 'input'">
<el-input v-model="dialogForm[item.name]"/>
</template>
</el-form-item>
……
<el-form-item>
<el-button type="primary" @click="submitForm(ruleFormRef)">Create</el-button>
</el-form-item>
</el-form>
……
<script lang="ts" setup>
import { ref,toRefs, defineProps,computed,defineEmits } from "vue";
import type { FormInstance } from 'element-plus'
const props = defineProps({
form: Array,
filed:Object,
});
const {form,labelWidth} = toRefs(props);
const dialogForm = computed(() => props.filed);
const ruleFormRef = ref<FormInstance>()
interface Datatemp {
label:string,
type:string,
name:string,
required?:Boolean,
message?:string,
rule?:Array<object>
option?:Array<object>
}
const TemplateFormat = (data:Datatemp,prop:string) => {
if(data[prop as keyof Datatemp]&&data[prop as keyof Datatemp]!=null&&data[prop as keyof Datatemp]!=''){
return data[prop as keyof Datatemp];
}else{
if (data.type == "input") {
return `请输入${data.label}`;
} else if (data.type == "select") {
return `请选择${data.label}`;
}
}
};
const ruleData = (data:Datatemp)=>{
let ruleArray=[];
if(data.required){
let message=data.message?data.message:TemplateFormat(data,'message')
let action = data.type=='input'?'blur':'change';
ruleArray.push({ required: true, message: message, trigger:action})
}
if(data.rule&&Array.isArray(data.rule)&&data.rule.length>0){
ruleArray=[...ruleArray,...data.rule]
}
return ruleArray
}
const emit = defineEmits(['submitVal'])
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
if (valid) {
emit('submitVal', dialogForm.value);
} else {
console.log('error submit!', fields)
}
})
}
</script>
大致讲解:ruleData函数中,接收每个项的rules,required,和message
- 首先判断required是否有值且为true
- 接着就是判断message,如果有传入message,则按照传入message展示即可,如果没有,则判断input和select不同类型,配置默认的message(在TemplateFormat函数中)。
- 根据以上两项,在rules数组中添加一项必填的规则
- 最后根据传入的rules,添加剩下的规则即可。
个性化定制placeholder和labelWidth
- 个性化定制placeholder
在业务组件传入的配置项placeholder,那么在子组件可根据是否传入placeholder,如果没有,可通过TemplateFormat函数配置默认的placeholder
- 个性化定制labelWidth
在业务组件传入labelWidth的值,然后在子组件相应配置即可。
子组件代码如下:
父组件代码如下