全代码框架文档
首页
快速上手
前端组件
前端二开
首页
快速上手
前端组件
前端二开
  • 二开前准备
  • 对接移动办公
  • 表单介绍

    • 表单封装逻辑
    • 传值和formModel
    • 组件的封装
    • 显示隐藏控制
    • 字段事件
  • 基础二开

    • 值计算
    • 修改组件值
    • 自定义校验
    • 使用远程数据源
    • 为工具栏添加按钮
    • 为表单添加新字段
  • 高级二开

    • 自定义字段
    • 自定义页面
    • 弹窗
    • 表单
    • 表格

自定义表单

提示:完整的流程审批表单因为流程权限等过于复杂所以不建议手写,最好还是用系统生成及拆分的代码进行二开,以下叙述的场景仅限于简单表单或者是对原表单的扩展。

PC端

项目引入了ant-design-vue的表单组件,具体文档点击查看 简单的并且可复用的表单,可以使用和框架表单一样的形式,编写一个公共组件,通过config.ts来编写表单配置,然后使用公共组件simpleFormItem来渲染表单各个字段的组件。这样可以做到表单的复用,减少代码量。

<template>
    <div class="form">
        <Form ref="formRef" :model="record">
            <Row>
                <template v-for="schema in config.schemas" :key="schema.field">
                    <Col :span="getColWidth(schema)">
                        <SimpleFormItem v-model:value="schema[schema.field]" :schema="schema" :refreshFieldObj="refreshFieldObj"/>
                    </Col>
                </template>
            </Row>
        </Form>
    </div>
</template>
<script lang="ts" setup>
import { onMounted, ref,unref, defineProps, watch, nextTick, computed, provide } from 'vue';
import SimpleFormItem from '/@/components/SimpleForm/src/components/SimpleFormItem.vue';
import { Form, Row, Col } from 'ant-design-vue';
const props = defineProps({
    record: {
        type: Object
    },
    config: {
        type: Object
    }
});

provide('formModel', props.record);
provide('formProps', ref(props.config.schemas));
const refreshFieldObj = ref<object>({});
const refreshAPI = (field) => {
    if (!field) return;
    if (!Object.keys(unref(refreshFieldObj)).includes(field)) {
        unref(refreshFieldObj)[field] = 0;
    }
    unref(refreshFieldObj)[field]++;
};
const wrapWidth = ref(1080);
function getColWidth(schema) {
    const compProps = schema.componentProps;
    if (compProps?.responsive) {
        if (compProps.respNewRow) {
            return 24; // 响应式布局下独立成行
        } else {
            const wrapValue = wrapWidth.value;
            if (wrapValue > import.meta.env.VITE_RESP_LG_WIDTH) {
                return 8;
            } else if (wrapValue > import.meta.env.VITE_RESP_MD_WIDTH) {
                return 12;
            } else {
                return 24;
            }
        }
    }
    return schema.colProps?.span;
}
</script>
<style lang="less" scoped>
.views-item {
    padding: 20px;
    margin-top: 16px;
    height: 700px;
    overflow-y: scroll;
}
:deep(.ant-input-disabled) {
    background-color: transparent;
    border: none;
}

:deep(.ant-form-item-label > label) {
    white-space: normal;
    display: inline;
    line-height: 32px;
}
</style>
<style lang="less">
.ant-input-affix-wrapper-disabled{
    background-color: #fff;
}
.ant-select-disabled {
    .ant-select-selector {
        border: none !important;
        background-color: transparent !important;
        padding-left: 0 !important;
    }

    .ant-select-selection-item {
        color: rgb(0 0 0 / 85%) !important;
    }

    .ant-select-arrow {
        display: none;
    }
}
</style>

当然如果个性化差异比较大,也可以自己写手写表单的各个组件。

<template>
    <template>
    <div class="views-item">
        <Form ref="formRef" :model="record">
            <Row>
                    <Col :span="12">
                        <FormItem label="责任类型" name="responsibilityType" :rules="[{ required: true, message: '请选择责任类型' }]">
                            <Select v-model="record.responsibilityType" :options="responsibilityTypeOptions" placeholder="请选择责任类型" allowClear />
                        </FormItem>
                    </Col>
                    <!--以下不一一列举-->
            </Row>
        </Form>
    </div>
</template>
<style lang="less" scoped>
    :deep(.ant-form-item-label > label) {
        white-space: normal;
        display: inline;
        line-height: 32px;
    }
</style>
<style lang="less">
    .ant-select-disabled {
        .ant-select-selector {
            border: none !important;
            background-color: transparent !important;
            padding-left: 0 !important;
        }

        .ant-select-selection-item {
            color: rgb(0 0 0 / 85%) !important;
        }

        .ant-select-arrow {
            display: none;
        }
    }
</style>

如果想主动进行表单校验,可以使用ref来获取表单实例,然后调用validate方法进行校验。这里校验的返回值是一个Promise,需要使用await进行等待。resolve的值是一个对象,如果校验成功则为表单包含数据,如果校验失败则为失败信息。

const formRef = ref(); // 表单实例
const validate = async () => { // 表单校验
    return await unref(formRef)?.validate(); // 表单校验
}

也可以使用相同方法触发重置表单(resetFields)、移除校验结果(clearValidate)等操作。

移动端

项目使用了uniapp的组件,组件源码均在路径@/uni_module下,表单组件在@/uni_module/uni-forms/components下,配置项和PC端类似。参照实际情况即可,可以自己编写也可以直接使用。

Last Updated:: 4/18/25, 3:41 PM
Contributors: DESKTOP-45LLIKH\11405
Prev
弹窗
Next
表格