Skip to content

表单控件

vue-admin-kit 内置多种表单控件,通过 type 属性指定。这些控件可以在 searchConfigformConfig 中使用。

控件类型总览

类型说明特有属性
input输入框suffix, suffixType
textarea多行输入rows, maxlength
number数字输入min, max, precision, step, suffix, stepStrictly, width
select下拉选择options, dictType, multiple, filterable, remote, remoteParam, change
radio单选options, dictType
date日期选择dateType, format, valueFormat
time时间选择timeFormat, isRange, rangeSeparator
upload文件上传uploadConfigList
uploadCard卡片上传uploadConfigList
editor富文本编辑器-
line分割线btnClick, btnTitle, style
inputGroup输入组children, labelWidth, labelPosition
addableInputGroup可增删输入组separator, minCount
selectChange搜索选择dictType, change, mounted

通用属性

所有表单控件都支持以下通用属性:

属性类型默认值说明
typestring-组件类型(必填)
propstring-字段名(必填)
labelstring-标签文本
spannumber12栅格占位(24 栅格)
requiredboolean | Functionfalse是否必填,支持函数动态判断
rulesFormItemRule[]-校验规则
defaultValueany-默认值
disabledbooleanfalse是否禁用
readonlybooleanfalse是否只读
editDisabledbooleanfalse编辑时是否禁用(新增可用)
placeholderstring-占位文本
showboolean | Functiontrue显示条件

通用属性完整示例

typescript
import { defineFormConfig } from "vue-admin-kit";

const formConfig = defineFormConfig([
  {
    type: "input",
    prop: "name",
    label: "名称",
    span: 12, // 占半行
    required: true, // 必填
    disabled: false, // 不禁用
    readonly: false, // 不只读
    editDisabled: true, // 编辑时禁用
    placeholder: "请输入名称",
    defaultValue: "", // 默认值
    rules: [
      // 自定义校验规则
      { min: 2, max: 20, message: "长度在 2 到 20 个字符", trigger: "blur" },
    ],
  },
]);

动态必填示例

typescript
const formConfig = defineFormConfig([
  {
    type: "select",
    prop: "status",
    label: "状态",
    dictType: "sys_status",
  },
  {
    type: "input",
    prop: "reason",
    label: "原因",
    // 当状态为 0(禁用)时必填
    required: ({ formData }) => formData.status === "0",
  },
]);

条件显示示例

typescript
const formConfig = defineFormConfig([
  {
    type: "select",
    prop: "type",
    label: "类型",
    options: [
      { label: "类型A", value: "a" },
      { label: "类型B", value: "b" },
      { label: "其他", value: "other" },
    ],
  },
  {
    type: "input",
    prop: "otherReason",
    label: "其他原因",
    // 当类型为 other 时显示
    show: ({ formData }) => formData.type === "other",
  },
]);

Input 输入框

基础输入框组件,支持后缀显示。

属性

属性类型默认值说明
suffixstring-后缀内容
suffixTypestring-后缀类型:text / icon / component

完整示例

typescript
const formConfig = defineFormConfig([
  // 基础输入框
  {
    type: "input",
    prop: "name",
    label: "名称",
    placeholder: "请输入名称",
    required: true,
    span: 12,
  },

  // 带文本后缀
  {
    type: "input",
    prop: "weight",
    label: "重量",
    placeholder: "请输入重量",
    suffix: "kg",
    suffixType: "text",
  },

  // 带图标后缀
  {
    type: "input",
    prop: "search",
    label: "搜索",
    placeholder: "请输入关键词",
    suffix: "el-icon-search",
    suffixType: "icon",
  },

  // 只读输入框
  {
    type: "input",
    prop: "code",
    label: "编码",
    readonly: true,
    placeholder: "系统自动生成",
  },

  // 编辑时禁用
  {
    type: "input",
    prop: "username",
    label: "用户名",
    editDisabled: true, // 新增时可编辑,编辑时禁用
    required: true,
  },
]);

Textarea 多行输入

多行文本输入框,支持字数限制和自动高度。

属性

属性类型默认值说明
rowsnumber4显示行数
maxlengthnumber-最大字符数

完整示例

typescript
const formConfig = defineFormConfig([
  // 基础多行输入
  {
    type: "textarea",
    prop: "remark",
    label: "备注",
    placeholder: "请输入备注信息",
    span: 24,
    rows: 4,
  },

  // 带字数限制
  {
    type: "textarea",
    prop: "description",
    label: "描述",
    placeholder: "请输入详细描述(最多500字)",
    span: 24,
    rows: 6,
    maxlength: 500, // 显示字数统计
  },

  // 必填的多行输入
  {
    type: "textarea",
    prop: "content",
    label: "内容",
    placeholder: "请输入内容",
    span: 24,
    rows: 8,
    required: true,
    rules: [{ min: 10, message: "内容至少10个字符", trigger: "blur" }],
  },

  // 只读多行输入
  {
    type: "textarea",
    prop: "systemLog",
    label: "系统日志",
    span: 24,
    rows: 10,
    readonly: true,
  },
]);

Number 数字输入

数字输入框,支持精度、范围和步长控制。

属性

属性类型默认值说明
minnumber-最小值
maxnumber-最大值
precisionnumber-数值精度(小数位数)
stepnumber1步长
suffixstring-后缀文本
widthstring100%组件宽度
stepStrictlybooleanfalse是否只能输入步长的倍数

完整示例

typescript
const formConfig = defineFormConfig([
  // 基础数字输入
  {
    type: "number",
    prop: "quantity",
    label: "数量",
    placeholder: "请输入数量",
    min: 1,
    max: 9999,
  },

  // 带精度的价格输入
  {
    type: "number",
    prop: "price",
    label: "价格",
    placeholder: "请输入价格",
    min: 0,
    max: 999999.99,
    precision: 2, // 保留2位小数
    step: 0.01,
    suffix: "元",
  },

  // 百分比输入
  {
    type: "number",
    prop: "discount",
    label: "折扣",
    placeholder: "请输入折扣",
    min: 0,
    max: 100,
    precision: 1,
    step: 0.5,
    suffix: "%",
  },

  // 步长严格模式
  {
    type: "number",
    prop: "boxCount",
    label: "箱数",
    placeholder: "请输入箱数",
    min: 0,
    max: 1000,
    step: 5,
    stepStrictly: true, // 只能输入5的倍数
  },

  // 自定义宽度
  {
    type: "number",
    prop: "score",
    label: "评分",
    placeholder: "0-100",
    min: 0,
    max: 100,
    precision: 0,
    width: "150px",
    suffix: "分",
  },

  // 必填数字
  {
    type: "number",
    prop: "amount",
    label: "金额",
    required: true,
    min: 0.01,
    precision: 2,
    suffix: "元",
    rules: [
      { type: "number", min: 0.01, message: "金额必须大于0", trigger: "blur" },
    ],
  },
]);

Select 下拉选择

下拉选择器,支持字典、静态选项、远程搜索和多选。

属性

属性类型默认值说明
dictTypestring-字典类型
optionsArray<{label, value}>-静态选项
filterablebooleanfalse是否可搜索
remotebooleanfalse是否远程搜索
remoteParamstring-远程搜索参数名
multiplebooleanfalse是否多选
changeFunction-值变化回调

完整示例

typescript
const formConfig = defineFormConfig([
  // 使用字典
  {
    type: "select",
    prop: "status",
    label: "状态",
    dictType: "sys_status",
    placeholder: "请选择状态",
    required: true,
  },

  // 使用静态选项
  {
    type: "select",
    prop: "category",
    label: "分类",
    placeholder: "请选择分类",
    options: [
      { label: "分类A", value: "a" },
      { label: "分类B", value: "b" },
      { label: "分类C", value: "c" },
    ],
  },

  // 可搜索下拉
  {
    type: "select",
    prop: "cityId",
    label: "城市",
    dictType: "city_list",
    placeholder: "请选择或搜索城市",
    filterable: true, // 本地搜索过滤
  },

  // 多选
  {
    type: "select",
    prop: "tags",
    label: "标签",
    dictType: "tag_list",
    placeholder: "请选择标签(可多选)",
    multiple: true,
    filterable: true,
  },

  // 远程搜索
  {
    type: "select",
    prop: "customerId",
    label: "客户",
    dictType: "customer_list", // 需要配置自定义适配器
    placeholder: "请输入客户名称搜索",
    filterable: true,
    remote: true,
    remoteParam: "customerName", // 搜索关键词参数名
  },

  // 值变化回调 - 联动清空
  {
    type: "select",
    prop: "provinceId",
    label: "省份",
    dictType: "province_list",
    placeholder: "请选择省份",
    change: ({ formData, value, dictItem }) => {
      // 省份变化时清空城市
      formData.cityId = "";
      console.log("选中省份:", dictItem.label, "值:", value);
    },
  },

  // 值变化回调 - 自动填充
  {
    type: "select",
    prop: "productId",
    label: "产品",
    dictType: "product_list",
    placeholder: "请选择产品",
    filterable: true,
    change: ({ formData, dictItem }) => {
      // 选择产品后自动填充价格
      if (dictItem.raw) {
        formData.price = dictItem.raw.price;
        formData.unit = dictItem.raw.unit;
      }
    },
  },

  // 编辑时禁用
  {
    type: "select",
    prop: "type",
    label: "类型",
    dictType: "sys_type",
    placeholder: "请选择类型",
    editDisabled: true, // 编辑时不可修改
    required: true,
  },
]);

远程搜索配置

远程搜索需要配合自定义适配器使用:

typescript
// 配置自定义适配器
const customAdapters = {
  customer_list: {
    api: (params) => getCustomerList(params),
    params: ({ searchKey }) => ({
      customerName: searchKey, // searchKey 是搜索关键词
      pageSize: 20,
    }),
    transform: (res) =>
      res.data.map((item) => ({
        label: item.customerName,
        value: String(item.id),
        raw: item, // 保留原始数据,供 change 回调使用
      })),
  },
};

// 注册适配器
registerCustomAdapters(customAdapters);

Radio 单选

单选框组件,支持字典和静态选项。

属性

属性类型默认值说明
dictTypestring-字典类型
optionsArray<{label, value}>-静态选项

完整示例

typescript
const formConfig = defineFormConfig([
  // 使用字典
  {
    type: "radio",
    prop: "sex",
    label: "性别",
    dictType: "sys_user_sex",
    required: true,
  },

  // 使用静态选项
  {
    type: "radio",
    prop: "isEnabled",
    label: "是否启用",
    options: [
      { label: "是", value: "1" },
      { label: "否", value: "0" },
    ],
    defaultValue: "1",
  },

  // 布尔值选项
  {
    type: "radio",
    prop: "isPublic",
    label: "是否公开",
    options: [
      { label: "公开", value: true },
      { label: "私密", value: false },
    ],
    defaultValue: false,
  },

  // 数字值选项
  {
    type: "radio",
    prop: "level",
    label: "等级",
    options: [
      { label: "普通", value: 1 },
      { label: "VIP", value: 2 },
      { label: "SVIP", value: 3 },
    ],
    defaultValue: 1,
  },

  // 禁用状态
  {
    type: "radio",
    prop: "auditStatus",
    label: "审核状态",
    dictType: "audit_status",
    disabled: true, // 整体禁用
  },

  // 条件显示
  {
    type: "radio",
    prop: "payType",
    label: "支付方式",
    options: [
      { label: "在线支付", value: "online" },
      { label: "货到付款", value: "cod" },
    ],
    show: ({ formData }) => formData.orderType === "normal",
  },
]);

Date 日期选择

日期/日期时间/日期范围选择器。

属性

属性类型默认值说明
dateTypestringdate日期类型:date / datetime / daterange / datetimerange / month / year / week
formatstring自动显示格式
valueFormatstring自动值格式

完整示例

typescript
const formConfig = defineFormConfig([
  // 日期选择
  {
    type: "date",
    prop: "birthday",
    label: "生日",
    dateType: "date",
    placeholder: "请选择生日",
  },

  // 日期时间选择
  {
    type: "date",
    prop: "appointmentTime",
    label: "预约时间",
    dateType: "datetime",
    placeholder: "请选择预约时间",
    required: true,
  },

  // 日期范围选择
  {
    type: "date",
    prop: "dateRange",
    label: "有效期",
    dateType: "daterange",
    placeholder: "请选择日期范围",
    span: 12,
  },

  // 日期时间范围选择
  {
    type: "date",
    prop: "activityTime",
    label: "活动时间",
    dateType: "datetimerange",
    placeholder: "请选择活动时间范围",
    span: 24,
  },

  // 月份选择
  {
    type: "date",
    prop: "month",
    label: "月份",
    dateType: "month",
    placeholder: "请选择月份",
  },

  // 年份选择
  {
    type: "date",
    prop: "year",
    label: "年份",
    dateType: "year",
    placeholder: "请选择年份",
  },

  // 周选择
  {
    type: "date",
    prop: "week",
    label: "周",
    dateType: "week",
    placeholder: "请选择周",
  },

  // 自定义格式
  {
    type: "date",
    prop: "createTime",
    label: "创建时间",
    dateType: "datetime",
    format: "YYYY年MM月DD日 HH:mm", // 显示格式
    valueFormat: "YYYY-MM-DD HH:mm:ss", // 值格式
    placeholder: "请选择创建时间",
  },

  // 只读日期
  {
    type: "date",
    prop: "auditTime",
    label: "审核时间",
    dateType: "datetime",
    readonly: true,
  },
]);

Time 时间选择

时间选择器,支持单时间和时间范围。

属性

属性类型默认值说明
timeFormatstringHH:mm:ss时间格式:HH:mm:ss / HH:mm / mm:ss
isRangebooleanfalse是否为时间范围
rangeSeparatorstring-范围分隔符
startPlaceholderstring-开始时间占位文本
endPlaceholderstring-结束时间占位文本

完整示例

typescript
const formConfig = defineFormConfig([
  // 基础时间选择(时:分:秒)
  {
    type: "time",
    prop: "startTime",
    label: "开始时间",
    timeFormat: "HH:mm:ss",
    placeholder: "请选择开始时间",
  },

  // 时:分 格式
  {
    type: "time",
    prop: "workTime",
    label: "上班时间",
    timeFormat: "HH:mm",
    placeholder: "请选择上班时间",
  },

  // 分:秒 格式
  {
    type: "time",
    prop: "duration",
    label: "时长",
    timeFormat: "mm:ss",
    placeholder: "请选择时长",
  },

  // 时间范围
  {
    type: "time",
    prop: "businessHours",
    label: "营业时间",
    isRange: true,
    timeFormat: "HH:mm",
    rangeSeparator: "至",
    startPlaceholder: "开始时间",
    endPlaceholder: "结束时间",
    span: 12,
  },

  // 必填时间
  {
    type: "time",
    prop: "deliveryTime",
    label: "配送时间",
    timeFormat: "HH:mm",
    placeholder: "请选择配送时间",
    required: true,
  },

  // 只读时间
  {
    type: "time",
    prop: "recordTime",
    label: "记录时间",
    timeFormat: "HH:mm:ss",
    readonly: true,
  },
]);

Upload 文件上传

文件上传组件,支持多文件类型分组上传。

uploadConfigList 配置项

属性类型默认值说明
propstring-字段名
labelstring-标签文本
bizTypestring-业务类型(必填)
limitnumber99最大文件数
acceptstring*/*允许的文件类型
maxSizenumber30MB最大文件大小(字节)
multiplebooleantrue是否支持多选
compressbooleanfalse是否压缩图片
requiredbooleanfalse是否必填
disabledbooleanfalse是否禁用
spannumber12栅格占位

完整示例

typescript
const formConfig = defineFormConfig([
  // 单文件上传
  {
    type: "upload",
    prop: "avatar",
    label: "头像",
    span: 24,
    uploadConfigList: [
      {
        prop: "avatar",
        label: "上传头像",
        bizType: "avatar",
        limit: 1,
        accept: ".jpg,.jpeg,.png,.gif",
        maxSize: 5 * 1024 * 1024, // 5MB
        compress: true, // 压缩图片
        required: true,
      },
    ],
  },

  // 多文件上传
  {
    type: "upload",
    prop: "attachments",
    label: "附件",
    span: 24,
    uploadConfigList: [
      {
        prop: "attachment",
        label: "上传附件",
        bizType: "attachment",
        limit: 10,
        accept: ".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx",
        maxSize: 30 * 1024 * 1024, // 30MB
        multiple: true,
      },
    ],
  },

  // 多类型文件分组上传
  {
    type: "upload",
    prop: "documents",
    label: "证件资料",
    span: 24,
    uploadConfigList: [
      {
        prop: "idCard",
        label: "身份证",
        bizType: "id_card",
        limit: 2,
        accept: "image/*",
        compress: true,
        required: true,
        span: 12,
      },
      {
        prop: "license",
        label: "营业执照",
        bizType: "license",
        limit: 1,
        accept: "image/*,.pdf",
        required: true,
        span: 12,
      },
      {
        prop: "contract",
        label: "合同文件",
        bizType: "contract",
        limit: 5,
        accept: ".pdf,.doc,.docx",
        span: 24,
      },
    ],
  },

  // 禁用上传
  {
    type: "upload",
    prop: "files",
    label: "历史文件",
    span: 24,
    uploadConfigList: [
      {
        prop: "historyFile",
        label: "历史文件",
        bizType: "history",
        disabled: true, // 只能查看,不能上传
      },
    ],
  },
]);

UploadCard 卡片上传

卡片样式的文件上传,支持拖拽上传和多类型文件分组。

uploadConfigList 配置项

与 Upload 组件相同,额外支持:

属性类型默认值说明
listTypestringtext文件列表类型:text / picture / picture-card
dragbooleantrue是否启用拖拽上传

完整示例

typescript
const formConfig = defineFormConfig([
  // 图片卡片上传
  {
    type: "uploadCard",
    prop: "images",
    label: "产品图片",
    span: 24,
    uploadConfigList: [
      {
        prop: "coverImage",
        label: "封面图",
        bizType: "cover",
        limit: 1,
        accept: ".jpg,.jpeg,.png,.webp",
        compress: true,
        required: true,
        listType: "picture-card",
        span: 12,
      },
      {
        prop: "gallery",
        label: "产品图集",
        bizType: "gallery",
        limit: 9,
        accept: "image/*",
        compress: true,
        listType: "picture-card",
        span: 12,
      },
    ],
  },

  // 文档拖拽上传
  {
    type: "uploadCard",
    prop: "docs",
    label: "文档资料",
    span: 24,
    uploadConfigList: [
      {
        prop: "document",
        label: "拖拽上传文档",
        bizType: "document",
        limit: 20,
        accept: ".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt",
        maxSize: 50 * 1024 * 1024, // 50MB
        drag: true,
        listType: "text",
        span: 24,
      },
    ],
  },

  // 混合类型上传
  {
    type: "uploadCard",
    prop: "materials",
    label: "素材文件",
    span: 24,
    uploadConfigList: [
      {
        prop: "image",
        label: "图片素材",
        bizType: "image_material",
        limit: 20,
        accept: "image/*",
        compress: true,
        listType: "picture",
        span: 12,
      },
      {
        prop: "video",
        label: "视频素材",
        bizType: "video_material",
        limit: 5,
        accept: ".mp4,.avi,.mov,.wmv",
        maxSize: 100 * 1024 * 1024, // 100MB
        listType: "text",
        span: 12,
      },
    ],
  },
]);

Editor 富文本编辑器

基于 WangEditor 的富文本编辑器。

完整示例

typescript
const formConfig = defineFormConfig([
  // 基础富文本
  {
    type: "editor",
    prop: "content",
    label: "内容",
    span: 24,
    required: true,
  },

  // 文章详情
  {
    type: "editor",
    prop: "articleContent",
    label: "文章内容",
    span: 24,
    placeholder: "请输入文章内容",
    rules: [{ required: true, message: "请输入文章内容", trigger: "blur" }],
  },

  // 条件显示的富文本
  {
    type: "editor",
    prop: "richDescription",
    label: "富文本描述",
    span: 24,
    show: ({ formData }) => formData.useRichText === true,
  },
]);

注意

使用富文本编辑器需要安装依赖:

bash
pnpm add @wangeditor/editor @wangeditor/editor-for-vue

Line 分割线

表单中的分割线,用于分组显示。

属性

属性类型默认值说明
labelstring-分割线标题
btnTitlestring-按钮文本
btnClickFunction-按钮点击回调
styleobject-自定义样式
spannumber24栅格占位

完整示例

typescript
const formConfig = defineFormConfig([
  // 简单分割线
  {
    type: "line",
    label: "基本信息",
  },
  { type: "input", prop: "name", label: "名称" },
  { type: "input", prop: "code", label: "编码" },

  // 带按钮的分割线
  {
    type: "line",
    label: "联系人信息",
    btnTitle: "添加联系人",
    btnClick: ({ formData }) => {
      // 添加联系人逻辑
      if (!formData.contacts) {
        formData.contacts = [];
      }
      formData.contacts.push({ name: "", phone: "" });
    },
  },

  // 自定义样式
  {
    type: "line",
    label: "重要信息",
    style: {
      color: "#f56c6c",
      fontSize: "16px",
      borderBottom: "2px solid #f56c6c",
    },
  },

  // 无标题分割线
  {
    type: "line",
    style: {
      borderBottom: "1px dashed #dcdfe6",
      marginBottom: "20px",
    },
  },

  // 带操作按钮的分组
  {
    type: "line",
    label: "收货地址",
    btnTitle: "新增地址",
    btnClick: ({ formData }) => {
      // 打开新增地址弹窗
      console.log("新增地址", formData);
    },
  },
]);

InputGroup 输入组

多个输入框的固定组合。

属性

属性类型默认值说明
childrenArray-子输入配置(必填)
labelWidthstring-标签宽度
labelPositionstringright标签位置:left / right / top

children 子项配置

属性类型说明
typestring组件类型:input / textarea
propstring字段名
labelstring标签文本

完整示例

typescript
const formConfig = defineFormConfig([
  // 地址输入组
  {
    type: "inputGroup",
    prop: "address",
    label: "地址",
    span: 24,
    labelWidth: "80px",
    labelPosition: "right",
    children: [
      { type: "input", prop: "province", label: "省" },
      { type: "input", prop: "city", label: "市" },
      { type: "input", prop: "district", label: "区" },
      { type: "input", prop: "street", label: "街道" },
      { type: "textarea", prop: "detail", label: "详细地址" },
    ],
  },

  // 联系方式输入组
  {
    type: "inputGroup",
    prop: "contact",
    label: "联系方式",
    span: 24,
    children: [
      { type: "input", prop: "contactName", label: "联系人" },
      { type: "input", prop: "contactPhone", label: "电话" },
      { type: "input", prop: "contactEmail", label: "邮箱" },
    ],
  },

  // 银行信息输入组
  {
    type: "inputGroup",
    prop: "bankInfo",
    label: "银行信息",
    span: 24,
    labelPosition: "top",
    children: [
      { type: "input", prop: "bankName", label: "开户银行" },
      { type: "input", prop: "bankAccount", label: "银行账号" },
      { type: "input", prop: "accountName", label: "户名" },
    ],
  },
]);

AddableInputGroup 可增删输入组

支持动态添加/删除的输入组,返回逗号分隔字符串或数组。

属性

属性类型默认值说明
separatorstring,分隔符(字符串模式)
minCountnumber1最少输入框数量

完整示例

typescript
const formConfig = defineFormConfig([
  // 基础可增删输入
  {
    type: "addableInputGroup",
    prop: "phones",
    label: "联系电话",
    placeholder: "请输入电话号码",
    span: 24,
  },

  // 自定义分隔符
  {
    type: "addableInputGroup",
    prop: "emails",
    label: "邮箱地址",
    placeholder: "请输入邮箱",
    separator: ";", // 使用分号分隔
    span: 24,
  },

  // 最少保留2个输入框
  {
    type: "addableInputGroup",
    prop: "keywords",
    label: "关键词",
    placeholder: "请输入关键词",
    minCount: 2, // 至少2个
    span: 24,
  },

  // 必填的可增删输入
  {
    type: "addableInputGroup",
    prop: "tags",
    label: "标签",
    placeholder: "请输入标签",
    required: true,
    span: 24,
    rules: [{ required: true, message: "请至少输入一个标签", trigger: "blur" }],
  },
]);

数据格式说明

typescript
// 字符串模式(默认)
// 输入: ["标签1", "标签2", "标签3"]
// 输出: "标签1,标签2,标签3"

// 数组模式(当 modelValue 初始为数组时)
// 输入: ["标签1", "标签2", "标签3"]
// 输出: ["标签1", "标签2", "标签3"]

详细用法请参考 AddableInputGroup 组件

SelectChange 搜索选择

带搜索框的选择组件,常用于关联数据选择。

属性

属性类型默认值说明
dictTypestring-字典类型(必填)
changeFunction-值变化回调
mountedFunction-组件挂载回调

change 回调参数

参数类型说明
pageDatapageDataType页面数据
formDataRecord<string>表单数据
valuestring选中的值
dictItemDictDataOption选中的字典项

mounted 回调参数

参数类型说明
pageDatapageDataType页面数据
formDataRecord表单数据
radioRef<any>单选值引用
searchQueryRef<string>搜索关键词引用
searchFunction搜索函数

完整示例

typescript
const formConfig = defineFormConfig([
  // 基础搜索选择
  {
    type: "selectChange",
    prop: "customerId",
    label: "客户",
    dictType: "customer_list",
    placeholder: "请输入客户名称搜索",
    span: 24,
  },

  // 带值变化回调
  {
    type: "selectChange",
    prop: "productId",
    label: "产品",
    dictType: "product_list",
    placeholder: "请输入产品名称搜索",
    span: 24,
    change: ({ formData, value, dictItem }) => {
      // 选择后自动填充其他字段
      formData.productName = dictItem.label;
      formData.productCode = dictItem.raw?.code;
      formData.price = dictItem.raw?.price;
      formData.unit = dictItem.raw?.unit;
      console.log("选中产品:", dictItem);
    },
  },

  // 带挂载回调(编辑时回显)
  {
    type: "selectChange",
    prop: "supplierId",
    label: "供应商",
    dictType: "supplier_list",
    placeholder: "请输入供应商名称搜索",
    span: 24,
    change: ({ formData, dictItem }) => {
      formData.supplierName = dictItem.label;
      formData.supplierContact = dictItem.raw?.contact;
    },
    mounted: ({ formData, radio, searchQuery, search }) => {
      // 编辑时回显已选择的供应商
      if (formData.supplierId) {
        radio.value = formData.supplierId;
        searchQuery.value = formData.supplierName || "";
        search(); // 触发搜索以显示选项
      }
    },
  },

  // 必填的搜索选择
  {
    type: "selectChange",
    prop: "warehouseId",
    label: "仓库",
    dictType: "warehouse_list",
    placeholder: "请输入仓库名称搜索",
    required: true,
    span: 24,
    change: ({ formData, dictItem }) => {
      formData.warehouseName = dictItem.label;
      formData.warehouseAddress = dictItem.raw?.address;
    },
  },
]);

配合自定义适配器使用

typescript
// 配置自定义适配器
const customAdapters = {
  customer_list: {
    api: (params) => searchCustomer(params),
    params: ({ searchKey }) => ({
      keyword: searchKey,
      status: "1",
      pageSize: 50,
    }),
    transform: (res) =>
      res.data.map((item) => ({
        label: `${item.customerName}(${item.customerCode})`,
        value: String(item.id),
        raw: item, // 保留原始数据
      })),
  },
};

registerCustomAdapters(customAdapters);

完整配置示例

以下是一个包含多种控件类型的完整表单配置示例:

typescript
import { defineFormConfig } from "vue-admin-kit";

const formConfig = defineFormConfig([
  // ==================== 基本信息 ====================
  { type: "line", label: "基本信息" },

  {
    type: "input",
    prop: "name",
    label: "名称",
    placeholder: "请输入名称",
    required: true,
    span: 12,
    rules: [
      { min: 2, max: 50, message: "长度在 2 到 50 个字符", trigger: "blur" },
    ],
  },

  {
    type: "input",
    prop: "code",
    label: "编码",
    placeholder: "系统自动生成",
    editDisabled: true, // 编辑时禁用
    span: 12,
  },

  {
    type: "select",
    prop: "status",
    label: "状态",
    dictType: "sys_status",
    placeholder: "请选择状态",
    required: true,
    defaultValue: "1",
    span: 12,
  },

  {
    type: "select",
    prop: "categoryId",
    label: "分类",
    dictType: "category_list",
    placeholder: "请选择分类",
    filterable: true,
    span: 12,
    change: ({ formData, dictItem }) => {
      formData.categoryName = dictItem.label;
    },
  },

  {
    type: "radio",
    prop: "type",
    label: "类型",
    options: [
      { label: "类型A", value: "a" },
      { label: "类型B", value: "b" },
      { label: "类型C", value: "c" },
    ],
    defaultValue: "a",
    span: 12,
  },

  {
    type: "radio",
    prop: "isPublic",
    label: "是否公开",
    dictType: "sys_yes_no",
    defaultValue: "1",
    span: 12,
  },

  // ==================== 数值信息 ====================
  { type: "line", label: "数值信息" },

  {
    type: "number",
    prop: "price",
    label: "单价",
    placeholder: "请输入单价",
    min: 0,
    max: 999999.99,
    precision: 2,
    step: 0.01,
    suffix: "元",
    required: true,
    span: 8,
  },

  {
    type: "number",
    prop: "quantity",
    label: "数量",
    placeholder: "请输入数量",
    min: 1,
    max: 99999,
    precision: 0,
    step: 1,
    suffix: "件",
    span: 8,
  },

  {
    type: "number",
    prop: "discount",
    label: "折扣",
    placeholder: "请输入折扣",
    min: 0,
    max: 100,
    precision: 1,
    step: 0.5,
    suffix: "%",
    defaultValue: 100,
    span: 8,
  },

  // ==================== 时间信息 ====================
  { type: "line", label: "时间信息" },

  {
    type: "date",
    prop: "startDate",
    label: "开始日期",
    dateType: "date",
    placeholder: "请选择开始日期",
    required: true,
    span: 12,
  },

  {
    type: "date",
    prop: "endDate",
    label: "结束日期",
    dateType: "date",
    placeholder: "请选择结束日期",
    span: 12,
  },

  {
    type: "date",
    prop: "createTime",
    label: "创建时间",
    dateType: "datetime",
    placeholder: "请选择创建时间",
    span: 12,
  },

  {
    type: "time",
    prop: "workTime",
    label: "工作时间",
    timeFormat: "HH:mm",
    placeholder: "请选择工作时间",
    span: 12,
  },

  // ==================== 联系信息 ====================
  {
    type: "line",
    label: "联系人信息",
    btnTitle: "添加联系人",
    btnClick: ({ formData }) => {
      if (!formData.contacts) formData.contacts = [];
      formData.contacts.push({ name: "", phone: "" });
    },
  },

  {
    type: "selectChange",
    prop: "customerId",
    label: "关联客户",
    dictType: "customer_list",
    placeholder: "请输入客户名称搜索",
    span: 24,
    change: ({ formData, dictItem }) => {
      formData.customerName = dictItem.label;
      formData.customerPhone = dictItem.raw?.phone;
      formData.customerAddress = dictItem.raw?.address;
    },
    mounted: ({ formData, radio, searchQuery, search }) => {
      if (formData.customerId) {
        radio.value = formData.customerId;
        searchQuery.value = formData.customerName || "";
        search();
      }
    },
  },

  {
    type: "addableInputGroup",
    prop: "phones",
    label: "联系电话",
    placeholder: "请输入电话号码",
    minCount: 1,
    span: 24,
  },

  // ==================== 附件信息 ====================
  { type: "line", label: "附件信息" },

  {
    type: "uploadCard",
    prop: "images",
    label: "图片",
    span: 24,
    uploadConfigList: [
      {
        prop: "coverImage",
        label: "封面图",
        bizType: "cover",
        limit: 1,
        accept: ".jpg,.jpeg,.png,.webp",
        compress: true,
        required: true,
        listType: "picture-card",
        span: 12,
      },
      {
        prop: "gallery",
        label: "图片集",
        bizType: "gallery",
        limit: 9,
        accept: "image/*",
        compress: true,
        listType: "picture-card",
        span: 12,
      },
    ],
  },

  {
    type: "upload",
    prop: "files",
    label: "附件",
    span: 24,
    uploadConfigList: [
      {
        prop: "attachment",
        label: "上传附件",
        bizType: "attachment",
        limit: 10,
        accept: ".pdf,.doc,.docx,.xls,.xlsx",
        maxSize: 30 * 1024 * 1024,
        span: 24,
      },
    ],
  },

  // ==================== 其他信息 ====================
  { type: "line", label: "其他信息" },

  {
    type: "editor",
    prop: "content",
    label: "详细描述",
    span: 24,
    show: ({ formData }) => formData.useRichText !== false,
  },

  {
    type: "textarea",
    prop: "remark",
    label: "备注",
    placeholder: "请输入备注信息",
    span: 24,
    rows: 4,
    maxlength: 500,
  },
]);

搜索表单配置示例

搜索表单配置与表单配置类似,但通常更简洁:

typescript
import { defineSearchConfig } from "vue-admin-kit";

const searchConfig = defineSearchConfig([
  {
    type: "input",
    prop: "name",
    label: "名称",
    placeholder: "请输入名称",
    span: 8,
  },

  {
    type: "select",
    prop: "status",
    label: "状态",
    dictType: "sys_status",
    placeholder: "请选择状态",
    filterable: true,
    span: 8,
  },

  {
    type: "select",
    prop: "categoryId",
    label: "分类",
    dictType: "category_list",
    placeholder: "请选择分类",
    filterable: true,
    multiple: true, // 多选
    span: 8,
  },

  {
    type: "date",
    prop: "dateRange",
    label: "创建时间",
    dateType: "daterange",
    placeholder: "请选择日期范围",
    span: 8,
  },

  {
    type: "number",
    prop: "minPrice",
    label: "最低价格",
    placeholder: "最低价格",
    min: 0,
    precision: 2,
    suffix: "元",
    span: 4,
  },

  {
    type: "number",
    prop: "maxPrice",
    label: "最高价格",
    placeholder: "最高价格",
    min: 0,
    precision: 2,
    suffix: "元",
    span: 4,
  },

  // 条件显示的搜索项
  {
    type: "input",
    prop: "advancedKeyword",
    label: "高级搜索",
    placeholder: "请输入关键词",
    span: 8,
    show: (params) => params.showAdvanced === true,
  },
]);

Released under the MIT License.