PC端逻辑
未绑定流程的表单和带流程的标配单赋值逻辑基本一致,在原始框架中,带流程的表单详情取值实际上取得是流程保存的一份冗余数据,而列表读取的是原始表单的数据,这样会导致数据不一致。在后续版本中,这个问题已经被修复。
赋值过程(表单初始化)
以流程表单为例,入口页面为SystemForm/src/Form,异步组件加载完成之后,会调用loadingCompleted函数。这个函数会调用ref的setWorkFlowForm,函数定义位于生成代码的components/Form.vue中。
对于非新建场景,id(就是默认的rowKey)存在,因此会调用setFormDataFromId,重新查一次表单数据,避免数据不一致问题,此时formModel实际上是有值的,但是值来自流程冗余,因此因此会调用setFormDataFromId会重新覆盖formModel的值。
async function setWorkFlowForm(obj) {
try {
let flowData = changeWorkFlowForm(cloneDeep(formProps), obj);
let {buildOptionJson, uploadComponentIds, formModels, isViewProcess} = flowData;
data.formDataProps = buildOptionJson;
emits('changeUploadComponentIds', uploadComponentIds); //工作流中必须保存上传组件id【附件汇总需要】
if (isViewProcess) {
setDisabledForm(); //查看
}
state.formModel = formModels;
if (formModels[RowKey]) {
setFormDataFromId(formModels[RowKey], false)
}
} catch(ex) {
}
}
最后,这个函数会调用SimpleForm/SimpleFormSetup的setFieldsValue函数完成表单赋值,因此,最上面template里formModel的定义仅仅是为了防止初值没有报错。
async function setFormDataFromId(rowId, skipUpdate) {
try {
const record = await getDevgaofirst(rowId);
if (skipUpdate) {
return record;
}
setFieldsValue(record);
state.formModel = record;
await getFormDataEvent(formEventConfigs, state.formModel, systemFormRef.value, formProps.schemas); //表单事件:获取表单数据
return record;
} catch (error) {
}
}
取值过程(表单提交)
表单提交时调用的实际上是表单的校验函数,这个函数会返回表单的值:
async function saveLaunch() {
data.submitLoading = true;
loading.value = true;
try {
let validateForms = await formInformation.value.validateForm();
if (validateForms.length > 0) {
}
}
// 后面代码省略
}
需要注意的是,这个函数的返回值必须表单中有效的antd-vue表单字段,而且字段必须渲染出来(可以v-show不能v-if,隐藏字段会自动处理)。因此修改提交值可以在模块生成的form.vue中找到validate函数:
async function validate() {
let values = [];
try {
values = await systemFormRef.value?.validate();
//可以修改values,加入需要额外提交给后端的值
if (data.formDataProps.hiddenComponent?.length) {
// 其他代码省略
}
} finally {
}
return values;
}
表单值绑定(v-model)
在拆分后的CustomDevForm中,formModel为响应式的,下面是一个例子,直接利用formModel拼接字符串,同时保持表单样式(提交时不传值):
<template>
<!-- 其余代码省略 -->
<Col :span="getColWidth({responsive: true})">
<FormItem label="vmodel演示">
{{formModel.danXingWenBen5090 + '/' + formModel.danXingWenBen23227}}
</FormItem>
</Col>
</template>
效果如下: 
移动端逻辑
表述与PC端基本一致,不再赘述。流程表单赋值也修改为从原始表单获取而非流程表单。
赋值过程(表单初始化)
移动端赋值过程相对PC端简化很多,在流程层获取到流程数据后,向下传递,在FormInformation.vue层存贮到公共文件userFormInfo.js文件中。然后接着通过loadForm方法向下层组件传递。
// FormInformation.vue
function setFormModel() {
try {
if(state.platform=='wx'){
// 无关代码省略
}else{
for (let index = 0; index < itemRefs.value.length; index++) {
if (itemRefs.value[index]) {
if(JSON.stringify(forms.formModels[index])!="{}"){
//这里放入流程表单数据
itemRefs.value[index].loadForm(forms.formModels[index]);
}else{
itemRefs.value[index].init();
}
}
}
}
} catch (error) {
}
}
system-form层同样触发下层form的loadForm方法。
// system-form层
async function loadForm(formModel) {
await systemRef.value.loadForm(formModel)
}
在生成的表单文件form.vue中,通过传递过来的formModel的rowKey值查询一遍原始表单数据,最后赋值。
// form.vue
async function loadForm(val){
let id = val[rowKey]
formConfig.id = id;
const {
data
} = await getxxx(id);
if (data) {
await formRef.value.setFormData({...props.formModel, ...data})
}
}
取值过程(表单提交)
移动端与PC端不同的是,在提交表单的时候校验函数和获取表单值的函数是分别进行的,validate函数并没有返回表单的值。
// 流程提交参数
async function saveLaunch() {
try {
uni.showLoading();
// 校验表单
let validateForms = await flowInfoRef.value.validateForm();
if (validateForms.length > 0) {
let successValidate = validateForms.filter((ele) => {
return ele.validate;
});
if (successValidate.length == validateForms.length) {
// 获取表单值
mainFormModels.value = await flowInfoRef.value.getFormModels();
// 其他代码省略
}
}
}
// 其他代码省略
}
这里获取表单值的函数的最底层是在simpleForm.vue公共组件,在这里getFormData函数返回与表单双向绑定的formModelRef的值,然后每一层都有一个getFormData函数向外暴露,以方便在最外层获取表单的值。在FormInformation.vue中,因为原始框架支持多表单,所以对多个表单值进行了合并处理。
async function getFormModels() {
let formModes = {};
if(state.platform=='wx'){
// 无关代码省略
}else{
for (let index = 0; index < forms.configs.length; index++) {
if (itemRefs.value[index]) {
try {
let formModel = await itemRefs.value[index]?.getFormData();
if(itemRefs.value[index].formType==FormType.SYSTEM){
let formModelIdVal = await itemRefs.value[index]?.submit();
formModel = {...formModel,...formModelIdVal};
}
formModes[forms.configs[index].formKey] = formModel;
} catch (error) {
}
}
}
// 无关代码省略
}
}
表单值绑定(v-model)
该部分逻辑基本与PC端一致,不再赘述。