Skip to content
广告位招租

优质广告位诚邀合作

本广告位曝光量正火速攀升,用户触达规模呈爆发式增长!现向品牌开放合作,趁曝光增长红利期,抓紧机会拿下,让您的品牌借势破圈!

--总浏览量(次)
--总计访客(人)

dynamic-components v1.1.0

DictDynamicComponents 是一个基于 Vant Form 的动态表单组件,支持通过配置列表 componentList 动态渲染多种表单组件,具备表单数据双向绑定、灵活的显示/隐藏规则、自定义校验逻辑、响应式布局等功能,适用于复杂表单场景(如动态表单、条件显示表单、多类型组件混合表单等)。

复制成功
00:00

基础动态表单

vue
<template>
  <DictDynamicComponents 
    v-model="formData" 
    :componentList="componentList" 
    @pass="handlePass" 
    @fail="handleFail"
    @action="handleAction"
  />
</template>

<script setup>
import { ref } from 'vue';

// 表单数据
const formData = ref({
  username: '',
  age: null,
  gender: 'male'
});

// 组件配置列表
const componentList = [
  {
    compName: 'VanField', // 组件名(Vant组件)
    isFormData: true, // 是否绑定表单数据
    fieldName: 'username', // 绑定的字段名
    props: {
      label: '用户名',
      placeholder: '请输入用户名',
      rules: [{ required: true, message: '用户名不能为空' }]
    }
  },
  {
    compName: 'VanField',
    isFormData: true,
    fieldName: 'age',
    props: {
      label: '年龄',
      type: 'number',
      placeholder: '请输入年龄'
    }
  },
];

// 校验通过回调
const handlePass = (formData, item) => {
  console.log('表单校验通过', formData, item);
};

// 校验失败回调
const handleFail = (errors) => {
  console.log('表单校验失败', errors);
};

// 校验失败回调
const handleAction = (item, formData) => {
  console.log('action动作', item, formData);
};
</script>

Props 说明

参数名类型默认值说明
modelValueObject{}表单数据对象(支持 v-model 双向绑定)
rulesObject{}全局表单验证规则,键为字段名,值为验证规则数组(同 Vant Form 规则)
idFieldString"id"组件配置项中用于标识唯一ID的字段名(用于依赖排序)
componentListArray[]动态组件配置列表(核心配置,每项为一个组件的详细配置,见下方说明)
isScrollToFormErrorBoolean有配置此属性时可覆盖全局 校验失败时是否自动滚动到错误位置 动态组件配置的此字段
...-对应组件支持van-form的其他原生属性(如 VanField 的 type、VanSelect 的 options 等)

组件配置项(componentList 每项属性)

属性名类型说明
compNameString组件名称(如 "VanField"、"VanSelect"、"VanRadioGroup" 等 Vant 组件)
isFormDataBoolean是否绑定表单数据(true 则通过 fieldName 与 formData 关联)
fieldNameString绑定的表单字段名(isFormData 为 true 时必填)
hiddenBooleanhidden为true时,无论如何组件都不可见
visibleBoolean初始可见性(默认 true,可通过 showRules 动态控制)
showRulesArray,Object,String显示/隐藏规则(见下方「显示规则详解」)
showRuleTypeString显示规则类型(默认 全局动态组件配置的值 "compare",可选 "calculate"、"validate" 等)
validatorRuleTypeString验证规则类型(默认 全局动态组件配置的值 "compare",可选 "calculate" 等)
propsObject组件属性(传递给 compName 对应的组件,如 label、placeholder 等)

props 常用属性

属性名类型说明
labelString组件标签文本
placeholderString占位提示文本(默认根据组件类型自动生成,如输入类为"请输入",选择类为"请选择")
rulesArray组件级验证规则(优先级高于全局 rules,格式同 Vant Form 规则)
requiredBoolean是否必填(会自动关联验证规则)
slotListArray组件插槽配置(见下方「插槽说明」)
...-对应组件支持的其他原生属性(如 VanField 的 type、VanSelect 的 options 等)

事件说明

事件名说明回调参数
pass表单校验通过时触发(formData: Object, trigger: any) - 校验通过的表单数据及触发源
fail表单校验失败时触发errors: Array - 校验失败的错误信息数组
action组件内部触发的action事件该组件的配置 item 对象 (也就是componentList里面的具体一项),用于根据item值进行相应动作

方法说明

组件通过 defineExpose 暴露以下方法:

方法名说明返回值
getFormData获取当前可见组件的表单数据(自动过滤隐藏组件的字段)表单数据对象
resetFormData重置表单(恢复初始数据、重置验证状态、重新计算显示规则)-
getComponentRef获取指定字段的组件实例(不传参则返回所有组件实例)组件实例(或包含所有实例的对象)
getDynamicComponentsRef获取底层 VanForm 组件实例VanForm 实例

显示规则详解(showRules)

showRules 用于动态控制组件的显示/隐藏,支持多种规则类型,结合 showRuleType 生效:

1. 基础比较规则(showRuleType: "compare")

通过比较表单数据的值控制显示

第一层数组表示或

总体规则(第一层数组)

[规则1]:表示 规则1 的结果,结果为 true 时显示该组件

[规则1,规则2,规则3] 表示 规则1||规则2||规则3 的结果,结果为 true 时显示该组件

第二层数组表示且

规则1的规则(第二层数组)

[[规则1-1,规则1-2,规则1-3],[规则2-1,规则2-2,规则2-3], [规则3-1,规则3-2,规则3-3]] 表示 (规则1-1&&规则1-2&&规则1-3) || (规则2-1&&规则2-2&&规则2-3) || (规则3-1&&规则3-2&&规则3-3)

第三次数组表示具体比较规则

规则1-1的规则(第三层数组)

["值", "运算符", "值"]

值使用 ${}包裹,表示获取formData表单数据的某个字段的值,可以使用.获取子字段的值

运算符支持如下:

常用运算符

<>=====!=!==>=<=

特殊运算符

运算符作用描述示例条件配置适用场景
in字段值是否在目标数组中['${role}', 'in', ['admin', 'user']]检查角色是否在允许列表中
not in字段值是否不在目标数组中['${status}', 'not in', ['deleted']]排除某些状态值
includes字符串/数组是否包含目标值['${name}', 'includes', '张']检查姓名是否包含“张”字
not includes字符串/数组是否不包含目标值['${tags}', 'not includes', 'invalid']检查标签中是否没有“invalid”
between字段值是否在 [min, max] 闭区间内['${score}', 'between', [60, 100]]检查分数是否在60-100之间
regex字段值是否匹配正则表达式['${phone}', 'regex', /^1[3-9]\d{9}$/]验证手机号格式
startsWidth字段值以什么开头['${phone}', 'startsWidth', '123']验证手机号是否以123开头
endsWidth字段值是否以什么结尾['${phone}', 'regex', '123']验证手机号是否以123结尾
javascript
// 示例:当 gender 为 'female' 时显示该组件
showRules: [[['${gender}','===', 'female']]],
showRuleType: "compare"

// 示例:当 gender 为 'female' 或 'male' 时显示该组件
showRules: [[['${gender}','===', 'female']], [['${gender}','===', 'male']],
showRuleType: "compare"

// 示例:当 gender 为 'female' 且  like 为 'basketball' 时显示该组件
showRules: [[['${gender}','===', 'female'], ['${like}','===', 'basketball']]],
showRuleType: "compare"

2. 计算规则(showRuleType: "calculate")

数组形式

第一层表示或 [规则1,规则2,规则3] 表示 规则1||规则2||规则3 的结果,结果为 true 时显示该组件

第二层表示且

[[规则1-1,规则1-2,规则1-3]] 表示 规则1-1&&规则1-2&&规则1-3 的结果,结果为 true 时显示该组件

第三层表示具体计算规则

也是数组形式 [变量1,运算符,变量2] 第一个元素为变量,第二个元素为运算符,第三个元素为变量

变量又可以套用上述计算规则 如 [[变量1-1,运算符,变量1-2], '>', 变量2] 变量可以无限套用上述规则

javascript
// 示例:当 age > 18 且 isStudent 为 false 时显示
showRules: [[["${age}", '>', 18], ["${isStudent}", '===', false]]],
showRuleType: "calculate"

支持计算运算符比较运算符

计算运算符 +-*/%**

比较运算符 ===!====!=><>=<=

:::注意

第一层的运算符仅支持 比较运算符 非第一层的运算符仅支持 计算运算符 为了方便数字计算,变量值为纯数字的字符串时会被转化为数字类型,因此比较时请注意。

:::

3. 校验规则(showRuleType: "validate")

通过其他字段的校验状态控制显示,支持数组形式和字符串形式,字符串需表示多个时使用英文逗号隔开

javascript
// 示例:当 username 和 password 校验通过时显示  username和password为fieldName对应字段
showRules: ['username', 'password'],
showRuleType: "validate"
javascript
// 示例:当 username 和 password 校验通过时显示 username和password为fieldName对应字段
showRules: 'username,password',
showRuleType: "validate"

4. 逻辑组合规则(showRuleType: "(1||2)&&(3||4)")

通过逻辑运算符组合多种规则(支持嵌套 compare、calculate、validate 类型)

javascript
// 示例:(gender为female 且 age>18) 或 email校验通过 时显示
showRules: [
  { 
    type: "compare", 
    rules: [[['${gender}', '===', 'female' ], ['${age}', '>', 18]]] 
  },
  { type: "validate", rules: ['email'] }
],
showRuleType: "1||2" // 满足条件1 或 条件2即可

验证规则详解

验证规则支持组件级 props.rules 和全局 rules,格式同 Vant Form,扩展功能如下:

1. 内置验证器

内置了许多常用校验规则,也可以通过 dictConfig.validator 配置进行覆盖和添加全局验证函数,在规则中通过字符串引用:

javascript
// 全局配置示例(store中的dictConfig)
dictConfig.validator = {
  phone: (val) => /^1[3-9]\d{9}$/.test(val), // 手机号验证
  idCard: (val) => /^\d{17}[\dXx]$/.test(val) // 身份证验证
};

// 组件配置中使用
props: {
  rules: [{ 
    validator: 'phone', // 引用全局验证器
    message: '请输入正确的手机号' 
  }]
}

2. 支持字符串格式的正则表达式

当rules配置的 pattern 为字符串格式时,会自动给他进行 new RegExp() 处理,使之变成 正则表达式

javascript
props: {
  rules: [{ 
    pattern: "^1[3-9]\\d{9}$", // 此字符串会被new RegExp()处理 变成 /^1[3-9]\d{9}$/ 也就是验证手机号的正则
    message: '请输入正确的手机号' 
  }]
}

3. 动态验证规则

与上面的显示隐藏基本一致,唯一不同就是此处没有"validate"类型;通过数组形式定义条件验证,结合 validatorRuleType 生效:

javascript
// 示例:邮箱必填 且 age 必须大于 18 验证才会通过
props: {
  rules: [
    { required: true, message: '成年用户必须填写邮箱' }, // 验证规则
    {
      validator: [[["${age}", ">", 18]]]
    } 
  ]
},
validatorRuleType: "compare"
javascript
// 示例:邮箱必填 且 age1 + age2 必须大于 18 验证才会通过
props: {
  rules: [
    { required: true, message: '成年用户必须填写邮箱' }, // 验证规则
    {
      validator: [[[["${age1}", "+", "${age2}"], ">", 18]]]
    } 
  ]
},
validatorRuleType: "calculate"
javascript
// 示例:邮箱必填 且 age1 + age2 必须大于 18 验证才会通过
props: {
  rules: [
    { required: true, message: '成年用户必须填写邮箱' }, // 验证规则
    {
      validator: [
        {
          type: "calculate",
          rules: [[["${age1}", "+", "${age2}"], ">", 18]]
        },
        {
          type: "compare",
          rules: [[["${age}", "<", 6]]]
        }
      ]
    } 
  ]
},
validatorRuleType: "1||2"

插槽说明

通过组件配置的 props.slotList 可自定义组件内容,slotList 每项配置:

属性名类型说明
slotNameString插槽名称(如 "label"、"suffix" 等组件支持的插槽)
renderFunction,String渲染函数,入参为 { scope, formData }(scope为插槽作用域,formData为当前表单数据)

示例:

javascript
props: {
  slotList: [
    {
      slotName: "suffix", // 自定义后缀插槽
      render: "<span class=\"custom-suffix\">{{username ? '已输入username' : '未输入username'}}</span>"
    }
  ]
}

布局说明

组件对表单组件支持响应式布局,非表单组件默认百分百占比,根据屏幕宽度自动调整组件宽度:

  • 屏幕宽度 < 768px:默认占满宽度
  • 768px ≤ 宽度 < 1024px:默认占 50% 宽度
  • 1024px ≤ 宽度 < 1400px:默认占 33.333% 宽度
  • 宽度 ≥ 1400px:默认占 25% 宽度

可通过给组件添加类名强制指定宽度:

  • full:占 100% 宽度
  • half:占 50% 宽度
  • three:占 33.333% 宽度
  • four:占 25% 宽度

示例:

javascript
props: {
  class: 'half' // 强制占50%宽度
}

微信公众号【爆米花小布】

0%

置顶

置顶