122 lines
5.9 KiB
Markdown
122 lines
5.9 KiB
Markdown
|
|
## 如何对表单中的明细表进行二开
|
|||
|
|
**注意:框架的部分模版部分用了非空断言,如formModel![xxx],编译器报错可以去掉叹号,或者在script上加上lang="ts"**
|
|||
|
|
|
|||
|
|
明细表拆分比较复杂,首先,定义明细表文件,假设文件名为CascadeDetailTable.vue,如果一个表单有多个明细表需要修改,要注意文件名的语义。用下面的代码初始化文件:
|
|||
|
|
|
|||
|
|
```vue
|
|||
|
|
<template>
|
|||
|
|
<div class="form-detail-table">
|
|||
|
|
<!-- 这里的内容抄SubFormV2.vue,第一层div不需要复制过来 -->
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script lang="ts">
|
|||
|
|
import SubFormV2Setup from '/@/components/Form/src/components/SubFormV2Setup.vue';
|
|||
|
|
|
|||
|
|
export default {
|
|||
|
|
extends: SubFormV2Setup,
|
|||
|
|
setup(props, ctx) {
|
|||
|
|
const ret = SubFormV2Setup.setup(props, ctx);
|
|||
|
|
return {
|
|||
|
|
...ret
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
</script>
|
|||
|
|
```
|
|||
|
|
注意这里的div有个class,在继承模式下,scope语义会失效,导致样式无法继承,因此在基类文件的样式改成了传统的css嵌套写法。
|
|||
|
|
|
|||
|
|
如果认为SubFormV2的模版内容太多,影响开发,可以照着下面的注释进行裁剪,注意**为了文档长度注释中的代码只保留关键部分**,不要直接复制。
|
|||
|
|
|
|||
|
|
```vue
|
|||
|
|
<template>
|
|||
|
|
<a-table :bordered="showFormBorder" :columns="headColums.length > 0 ? headColums : columns" :data-source="addDataKey(data)" :pagination="showPagination ? { defaultPageSize: 10 } : false" :scroll="{ x: 'max-content' }">
|
|||
|
|
<template #summary>
|
|||
|
|
<!-- 求和汇总相关代码 没用到可以裁剪 -->
|
|||
|
|
</template>
|
|||
|
|
<template #bodyCell="{ column, record, index }">
|
|||
|
|
<template v-if="column.key !== 'action'">
|
|||
|
|
<template v-if="column.key === 'index'">
|
|||
|
|
<!-- 自动行号 建议保留 -->
|
|||
|
|
</template>
|
|||
|
|
<FormItem v-else :name="[mainKey, index, column.dataIndex]" :rules="rules(column, record, index)" :validateTrigger="['blur', 'change']">
|
|||
|
|
<!---如果是checked一类的组件-->
|
|||
|
|
<template v-if="checkedValueComponents.includes(column.componentType)">
|
|||
|
|
<component :is="componentMap.get(column.componentType)" v-model:checked="record[column.dataIndex]" :bordered="showComponentBorder" v-bind="getComponentsProps(column.componentProps, column.dataIndex, record, index)" />
|
|||
|
|
</template>
|
|||
|
|
<template v-else-if="column.componentType === 'RangePicker' || column.componentType === 'TimeRangePicker'">
|
|||
|
|
<!-- 没有用范围选择器可以不用,比如时间日期区间 -->
|
|||
|
|
</template>
|
|||
|
|
<template v-else-if="column.componentType === 'Render'">
|
|||
|
|
<!-- 没有自定义render组件可以不用,大多数开发都到不了这层 -->
|
|||
|
|
</template>
|
|||
|
|
<template v-else-if="column.key !== 'index'">
|
|||
|
|
<!-- 这一部分不能裁剪,要不组件就渲染不出来了 -->
|
|||
|
|
</template>
|
|||
|
|
</FormItem>
|
|||
|
|
</template>
|
|||
|
|
<template v-if="column.key === 'action' && !disabled">
|
|||
|
|
<!-- 行删除 建议保留 如果增加额外的行动作可以写到这里 -->
|
|||
|
|
</template>
|
|||
|
|
</template>
|
|||
|
|
</a-table>
|
|||
|
|
</template>
|
|||
|
|
```
|
|||
|
|
表格二开很简单,就是参照文档在#bodyCell中把对应的列的覆盖,一般用column.dataIndex进行覆盖,如果是对组件进行复写,还要将column.key !== 'index'这个条件下增加排除,因为这里是非特殊组件渲染的位置。
|
|||
|
|
|
|||
|
|
接下来,定义SimpleFormItem,假设文件名为SimpleTableItem.vue,这个组件不需要定义很多次,你可以根据表格的名称,或者是自定义参数,在一个文件里根据条件渲染多种表格:
|
|||
|
|
|
|||
|
|
```vue
|
|||
|
|
<template>
|
|||
|
|
<!-- formitem的标题一般不用,如果不需要控制明细表的权限显隐,这个formitem可以去掉,或者用div代替 -->
|
|||
|
|
<FormItem
|
|||
|
|
v-if="getShow(schema)"
|
|||
|
|
v-show="getIsShow(schema)"
|
|||
|
|
:key="schema.key"
|
|||
|
|
:label="getComponentsProps.showLabel ? schema.label : ''"
|
|||
|
|
:label-col="labelCol"
|
|||
|
|
:labelAlign="formProps?.labelAlign"
|
|||
|
|
:name="schema.field"
|
|||
|
|
:wrapperCol="itemLabelWidthProp.wrapperCol"
|
|||
|
|
>
|
|||
|
|
<!-- 这里原先是component is写法,现在需要换成你自己的明细表 -->
|
|||
|
|
<!-- 也可以根据v-if渲染不同表格,这样就不需要定义很多次FormItem了 -->
|
|||
|
|
<cascade-detail-table v-model:value="formModel![schema.field]" :disabled="getDisable" :size="formProps?.size" v-bind="schema.componentProps" />
|
|||
|
|
</FormItem>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script lang="ts">
|
|||
|
|
import SimpleFormItemSetup from '/@/components/SimpleForm/src/components/SimpleFormItemSetup.vue';
|
|||
|
|
import CascadeDetailTable from '/@/views/test/cascadeDemo/components/CascadeDetailTable.vue';
|
|||
|
|
|
|||
|
|
export default {
|
|||
|
|
extends: SimpleFormItemSetup,
|
|||
|
|
components: {
|
|||
|
|
CascadeDetailTable
|
|||
|
|
},
|
|||
|
|
setup(props, ctx) {
|
|||
|
|
const ret = SimpleFormItemSetup.setup(props, ctx);
|
|||
|
|
return {
|
|||
|
|
...ret
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
</script>
|
|||
|
|
```
|
|||
|
|
最后,在表单文件用用自定义的FormItem替换原有的组件。
|
|||
|
|
```vue
|
|||
|
|
<!-- 表格组件 -->
|
|||
|
|
<Col v-if="getIfShow2('25axx52')" v-show="getIsShow2('25a9xx35952')" :span="getColWidth(schemaMap['25a9xx52'])">
|
|||
|
|
<template v-if="showComponent(schemaMap['25a93xx5952'])">
|
|||
|
|
<!-- 这里原来是SimpleFormItem,注意选项写法所有的组件都需要引入后放到components里 -->
|
|||
|
|
<SimpleTableItem
|
|||
|
|
v-model:value="formModel[schemaMap['25a93xx52'].field]"
|
|||
|
|
:form-api="formApi"
|
|||
|
|
:isWorkFlow="isWorkFlow"
|
|||
|
|
:refreshFieldObj="refreshFieldObj"
|
|||
|
|
:schema="schemaMap['25a9xx952']"
|
|||
|
|
/>
|
|||
|
|
</template>
|
|||
|
|
</Col>
|
|||
|
|
```
|