网站后台管理系统如何使用,搜索引擎排名优化的关键是,网络服务主要包括哪几种,设计一个企业官网的栏目一、为什么表单要分组处理#xff1f;
方便表单字段的复用#xff1a;例如#xff0c;你的表单有十个字段会在很多的表单都会用到#xff0c;那么表单则需要进行分组进行表单复用#xff1b;实现不同角色的表单权限控制#xff1a;例如一个表单有60个字段#xff0c;角…一、为什么表单要分组处理
方便表单字段的复用例如你的表单有十个字段会在很多的表单都会用到那么表单则需要进行分组进行表单复用实现不同角色的表单权限控制例如一个表单有60个字段角色A拥有表单前30个的权限角色B拥有其它30个字段的权限正常想法可能会在表单的页面直接获取角色的权限通过v-if来控制不同字段的权限这样的话权限逻辑和表单逻辑就会堆砌在一起简单一点的表单可能没有太大影响如果表单逻辑很复杂或者表单字段过多就会导致代码的臃肿后期难以维护若表单进行了分组处理可以增加一个业务组件来处理权限的逻辑表单的校验等逻辑则在分组表单中完成。
二、表单分组处理实现思路
表单字段按业务逻辑进行划分成不同的组一个组代表一个表单子组件表单子组件实现校验字段的方法如果有需要重置表单字段需求则增加表单重置方法增加的校验方法校验成功则返回子表单所有字段否则返回null和表单重置方法在子组件onMounted钩子中将两个方法传递给业务组件父组件业务组件维护两个数组分别存储子表单组件的校验方法和重置表单方法用户点击提交表单或者重置表单时触发对应维护的数组即可
三、具体实现代码
3.1 将表单分为两组为例目录结构如下
效果图如下 3.2 ComplexForm.vue业务组件代码如下
script setup langts
import FormItemA from /views/component/complex-form/FormItemA.vue;
import FormItemB from /views/component/complex-form/FormItemB.vue;
import { reactive, provide, ref, onMounted } from vue;defineOptions({name: ComplexForm
});const formData ref({});
// 向子组件注入表单的初始化的值或者回填的值一般是编辑表单的时候需要传递
provide(defaultFormData, formData);const getFormData () {formData.value {name: Hello,region: shanghai,count: 5,date1: ,date2: ,delivery: false,type: [],resource: ,desc: hello world};
};
onMounted(() {});
// 将子组件表单的参数添加到formData中汇总
const addParamsToFormData (params: any) {Object.assign(formData.value, params);
};
const formEventList reactive([]);
// 存储子组件的表单验证方法在提交时统一调用
const addEventToFormEventList (event: Function) {formEventList.push(event);
};
const submitHandler () {let successFlag true;console.log(formEventList, formEventList);formEventList.forEach((func, index, list) {// 执行子组件的方法表单验证触发add-params添加参数func().then(res {if (!res) {// 如果表单存在一个不满足则设置标识为false后续根据这个标识来确定是否可以提交表单successFlag false;} else {// 表单验证通过后添加参数到formDataaddParamsToFormData(res);}// 执行最后一个表单验证并且通过后提交表单处理if (index list.length - 1 successFlag) {console.log(表单验证通过提交表单);}}).catch(err {console.log(返回错误, err);});});
};const formResetEvent reactive([]);
// 存储子组件的表单重置方法在重置时统一调用
const addFormResetEvent func {formResetEvent.push(func);
};
const resetForm () {formResetEvent.forEach(func {func();});
};
/scripttemplatediv{{ formData }}/divFormItemAadd-submit-eventaddEventToFormEventListadd-reset-eventaddFormResetEvent/FormItemBadd-submit-eventaddEventToFormEventListadd-reset-eventaddFormResetEvent/el-button typeprimary clicksubmitHandler表单提交/el-buttonel-button clickresetForm重置表单/el-buttonel-button clickgetFormData模拟接口请求表单回填数据/el-button
/templatestyle scoped langscss/style
3.2 FormItemA.vue 子组件代码如下
script langts setup
import {reactive,ref,defineEmits,onMounted,inject,watch,nextTick
} from vue;
import type { FormInstance, FormRules } from element-plus;interface RuleForm {name: string;region: string;count: string;
}interface Emits {(e: add-submit-event, event: Function): void;(e: add-reset-event, event: Function): void;
}
const emits defineEmitsEmits();// 接受注入的默认表单数据表单回填
const defaultFormData inject(defaultFormData);onMounted(() {// 将当前表单验证方法传递给父组件维护的数组父组件点击提交时统一遍历数组进行表单验证emits(add-submit-event, submitForm);emits(add-reset-event, resetForm);
});const setDefaultFormData (ruleForm, sourceForm) {console.log(666666--sourceForm, sourceForm);for (const key in ruleForm) {if (Object.prototype.hasOwnProperty.call(sourceForm, key)) {ruleForm[key] JSON.parse(JSON.stringify(sourceForm[key]));}}
};watch(() defaultFormData.value,() {console.log(watch监听);// 回填表单数据时需要加nextTick否则ruleFormRef.value.resetFields()初始化表单时会初始化为赋值后的表单数据无法达到真正初始化表单为空值nextTick(() {setDefaultFormData(ruleForm, defaultFormData.value);});},{immediate: true}
);const formSize ref(default);
const ruleFormRef refFormInstance();
const ruleForm reactiveRuleForm({name: Hello,region: ,count:
});const rules reactiveFormRulesRuleForm({name: [{ required: true, message: Please input Activity name, trigger: blur },{ min: 3, max: 5, message: Length should be 3 to 5, trigger: blur }],region: [{required: true,message: Please select Activity zone,trigger: change}],count: [{required: true,message: Please select Activity count,trigger: change}]
});// 单个表单提交校验通过则返回表单的字段校验失败则返回null
const submitForm () {return new Promise((resolve, reject) {if (!ruleFormRef.value) return resolve(null);ruleFormRef.value.validate((valid, fields) {if (valid) {console.log(formItemA---submit!);resolve(ruleForm);} else {resolve(null);}});});
};const resetForm () {if (!ruleFormRef.value) return;ruleFormRef.value.resetFields();
};const options Array.from({ length: 10000 }).map((_, idx) ({value: ${idx 1},label: ${idx 1}
}));
/scripttemplateel-formrefruleFormRef:modelruleForm:rulesruleslabel-width120pxclassdemo-ruleForm:sizeformSizestatus-iconel-form-item labelActivity name propnameel-input v-modelruleForm.name //el-form-itemel-form-item labelActivity zone propregionel-select v-modelruleForm.region placeholderActivity zoneel-option labelZone one valueshanghai /el-option labelZone two valuebeijing //el-select/el-form-itemel-form-item labelActivity count propcountel-select-v2v-modelruleForm.countplaceholderActivity count:optionsoptions//el-form-item/el-form
/template
3.3 FormItemB.vue 子组件代码如下
script langts setup
import {reactive,ref,defineEmits,onMounted,watch,nextTick,inject
} from vue;
import type { FormInstance, FormRules } from element-plus;interface RuleForm {date1: string;date2: string;delivery: boolean;type: string[];resource: string;desc: string;
}interface Emits {(e: add-submit-event, event: Function): void;(e: add-reset-event, event: Function): void;
}
const emits defineEmitsEmits();// 接受注入的默认表单数据表单回填
const defaultFormData inject(defaultFormData);onMounted(() {// 将当前表单验证方法传递给父组件维护的数组父组件点击提交时统一遍历数组进行表单验证emits(add-submit-event, submitForm);emits(add-reset-event, resetForm);
});const setDefaultFormData (ruleForm, sourceForm) {console.log(666666--sourceForm, sourceForm);for (const key in ruleForm) {if (Object.prototype.hasOwnProperty.call(sourceForm, key)) {ruleForm[key] JSON.parse(JSON.stringify(sourceForm[key]));}}
};watch(() defaultFormData.value,() {console.log(watch监听);// 回填表单数据时需要加nextTick否则ruleFormRef.value.resetFields()初始化表单时会初始化为赋值后的表单数据无法达到真正初始化表单为空值nextTick(() {setDefaultFormData(ruleForm, defaultFormData.value);});},{immediate: true}
);const formSize ref(default);
const ruleFormRef refFormInstance();
const ruleForm reactiveRuleForm({date1: ,date2: ,delivery: false,type: [],resource: ,desc:
});const rules reactiveFormRulesRuleForm({date1: [{type: date,required: true,message: Please pick a date,trigger: change}],date2: [{type: date,required: true,message: Please pick a time,trigger: change}],type: [{type: array,required: true,message: Please select at least one activity type,trigger: change}],resource: [{required: true,message: Please select activity resource,trigger: change}],desc: [{ required: true, message: Please input activity form, trigger: blur }]
});const submitForm () {return new Promise((resolve, reject) {if (!ruleFormRef.value) return resolve(null);ruleFormRef.value.validate((valid, fields) {if (valid) {console.log(formItemB---submit!);resolve(ruleForm);} else {// console.log(error submit!, fields);resolve(null);}});});
};const resetForm () {if (!ruleFormRef.value) return;ruleFormRef.value.resetFields();
};
/scripttemplateel-formrefruleFormRef:modelruleForm:rulesruleslabel-width120pxclassdemo-ruleForm:sizeformSizestatus-iconel-form-item labelActivity time requiredel-col :span11el-form-item propdate1el-date-pickerv-modelruleForm.date1typedatelabelPick a dateplaceholderPick a datestylewidth: 100%//el-form-item/el-colel-col classtext-center :span2span classtext-gray-500-/span/el-colel-col :span11el-form-item propdate2el-time-pickerv-modelruleForm.date2labelPick a timeplaceholderPick a timestylewidth: 100%//el-form-item/el-col/el-form-itemel-form-item labelInstant delivery propdeliveryel-switch v-modelruleForm.delivery //el-form-itemel-form-item labelActivity type proptypeel-checkbox-group v-modelruleForm.typeel-checkbox labelOnline activities nametype /el-checkbox labelPromotion activities nametype /el-checkbox labelOffline activities nametype /el-checkbox labelSimple brand exposure nametype //el-checkbox-group/el-form-itemel-form-item labelResources propresourceel-radio-group v-modelruleForm.resourceel-radio labelSponsorship /el-radio labelVenue //el-radio-group/el-form-itemel-form-item labelActivity form propdescel-input v-modelruleForm.desc typetextarea //el-form-item/el-form
/template