Skip to content

ConfigForm 配置表单 ​

介绍 ​

预设表单项目,通过配置生成表单,简化表单编码。

组合使用 config-form、config-footer,覆盖校验、条件显隐、回显格式化与底部操作等常见场景;可与 config-list、config-detail 搭配完成 CRUD。

基础用法 ​

传入 data(表单值)、items(字段配置)、actions(底部按钮,可选):

html
<config-form
  :data="form"
  :items="formItems"
  :actions="formActions"
/>
ts
import ConfigForm from '@/composites/config-form/index.vue';
import type { FormItem, FormAction } from '@/composites/config-form/types';

const form = ref<any>({});

const formItems = ref<FormItem[]>([
  {
    key: 'title',
    label: '标题',
    component: 'input',
    rules: ['required'],
    placeholder: '请输入标题',
  },
  {
    key: 'status',
    label: '状态',
    component: 'radio',
    options: [
      { label: '待处理', value: 'todo' },
      { label: '进行中', value: 'doing' },
    ],
  },
]);

const formActions = ref<FormAction[]>([
  {
    title: '提交',
    name: 'submit', // 会先校验,通过后再执行 action
    type: 'primary',
    action: (data) => {
      console.log('提交值', data);
    },
  },
]);

组件 Props ​

属性说明默认
data表单数据对象(双向绑定字段值)—
items字段配置列表—
actions底部操作(走 config-footer)—
theme主题:default / cardcard
labelPosition标签位置:left / toptop
requiredPosition必填星号位置:left / rightright
scrollOffsetTop校验失败滚动额外偏移0

字段配置 ​

每个字段至少需要 key、component;常用项如下:

字段说明
key数据键,唯一
label标签文案
component控件类型,见下表
rules校验:'required' / 'phone' / 'email' / 'idcard' 或自定义 FormItemRule
placeholder占位;必填失败时也会用于提示
options选项(radio / checkbox / picker / select / cascader)
attrs透传到底层控件的属性
show是否展示(仍占位/仍在表单中),可为函数 (form, value) => boolean
visible是否渲染;false 时不挂载该项,可为函数
formatter展示用格式化 (value, form) => any
dataKeygetData() 提交时的键名映射
dataFormattergetData() 提交时的值格式化
onChange值变化回调

支持的 component ​

component说明
input输入框,可配 unit
number数字,type: 'int' | 'float',可配 unit
textarea多行文本
rate评分
radio单选
checkbox多选
picker选择器
select选择组,可 multiple
cascader级联,可 multiple
date日期,type 支持 year / year-month / month-day / date
datetime日期时间,timeType: 'minute' | 'second'
calendar日历,可配 minDate / maxDate / disabled
upload上传,可配 minSize / maxSize(MB)

TIP

小程序不支持动态组件,字段需在 config-form 内静态引入;扩展新类型时在 composites 中增加对应 fields/* 并注册分支。

底部操作 ​

actions 中 name: 'submit' 的按钮会先执行表单校验,通过后再调用 action(data);data 为 getData() 的结果(含 dataKey / dataFormatter 映射)。

ts
const formActions = ref<FormAction[]>([
  {
    title: '取消',
    plain: true,
    action: () => uni.navigateBack(),
  },
  {
    title: '保存',
    name: 'submit',
    type: 'primary',
    action: async (data) => {
      await saveApi(data);
    },
  },
]);

也可不传 actions,自行用 ref 调用实例方法:validate、getData、clearValidate 等。

条件显隐 ​

  • visible:为 false 时不渲染字段(带动画收起),适合问卷分支。
  • show:为 false 时隐藏但仍保留在表单结构中。
ts
{
  key: 'otherHero',
  label: '其他英雄',
  component: 'input',
  rules: ['required'],
  visible: (form) => form.played === '1' && form.hero === '0',
}

回显与提交映射 ​

表单内部可用中文 key 绑定;提交时用 dataKey / dataFormatter 转成接口字段:

ts
{
  key: '昵称',
  label: '昵称',
  component: 'input',
  dataKey: 'nickname',
  dataFormatter: (value) => String(value).trim(),
}

formatter 只影响控件展示值,不改变 data[key] 原始存储(除非配合 onChange 自行写入)。

注意事项 ​

  1. data 需是响应式对象(ref / reactive),字段写入依赖同一引用。
  2. key 必须唯一,并与 data 上的字段对应。
  3. 选项类字段提供 options(或返回选项的函数);级联数据结构需符合控件约定。
  4. show vs visible:要「不占位、不参与展示」用 visible;仅视觉隐藏用 show。
  5. 提交取值用 getData()(或 name: 'submit' 的 action 参数),不要只读原始 data 若已配置 dataKey。
  6. 本案例源码在 example/src/composites/config-form,可按业务拷贝改造。

错误示范 ​

不要把非响应式普通对象当 data

ts
// ❌ 错误:赋值后视图不更新
const form = { title: '' };

// ✅ 正确
const form = ref({ title: '' });
// 或
const form = reactive({ title: '' });

不要混淆 show / visible

ts
// ❌ 错误:以为 show: false 会卸载字段,实际仍在表单中
{ key: 'a', component: 'input', show: () => false }

// ✅ 分支问卷、不渲染时用 visible
{ key: 'a', component: 'input', visible: (form) => form.type === '1' }

不要漏配 options

ts
// ❌ 错误:radio / picker 等无选项
{ key: 'status', component: 'radio', rules: ['required'] }

// ✅ 正确
{
  key: 'status',
  component: 'radio',
  rules: ['required'],
  options: [
    { label: '启用', value: '1' },
    { label: '停用', value: '0' },
  ],
}

提交勿忽略 dataKey

ts
// ❌ 错误:配置了 dataKey 却直接把 form 原样 POST
await api(form.value);

// ✅ 正确:用 getData() 或 submit action 的 data
const data = formRef.value?.getData();
await api(data);

赣ICP备2025061025号-1