动态表单与动态表格设计套路
需要提前掌握的知识
- 通过
<component is='xxx'></component>动态加载/切换组件 - 透传 Attributes, 移除 $listeners, $attrs 包含 class & style
- 自定义 v-model
- 通过 v-on 对象语法 传递事件, 声明触发的事件
- 通过 v-bind 对象语法 传递属性, v-bind 合并行为
- js 对象深度克隆
- 你真的了解 vue2.0 和 vue3.0 响应式原理区别吗?
重要说明
如果自定义v-model实际是一个对象,而组件内部会对 v-model 值的某些属性值进行修改, 那么不要将 v-model 的值设置为 null 或 undefined,然后再通过 withDefaults() 的形式,将 v-model 对应 props设置为 空对象或特定对象, 因为这将导致v-model无法进行响应式。表现形式就是。内部更新了v-model属性值,但界面实际无变化
动态表单哪些东西是动态的?
- 表单项可能是动态的
- 表单项的可选值可能是动态的
- 表单的验证规则也可能是动态的
实现套路
- 定义表单项配置
- 通过
import.mate.glob加载指定目录的所有表单项组件 - 将所有的表单项配置成一个数组
- 循环表单项配置数组,动态渲染成一个表单
一个完整的动态表单项配置
ts
import { FormItemRule } from 'element-plus'
import { Component } from 'vue'
/**
* 表单项规则创建函数
*
* @param formData 表单数据
* @param rowData 行数据
*
* @return {FormItemRule[] | undefined} 规则数组或undefined
*/
type RuleFactory<T extends DynFormData> = (
formData: T,
rowData?: Record<string, unknown>
) => FormItemRule[] | FormItemRule | undefined
/**
* 可选项
*/
export interface OptionType {
label: string
value: number | string
}
export type DynFormData = Record<string, unknown>
/**
* 表单项配置
*/
export interface FormItemConfig<T extends DynFormData> extends Record<string, unknown> {
/**
* el-form-item标签的prop
*/
prop: string
/**
* 表单项的组件类型. 不传表示ElInput
*/
type?: string
/**
* 组件lable
*/
label: string
/**
* 表单项验证规则
*/
rules?: FormItemRule | FormItemRule[] | RuleFactory<T>
/**
* 表单项目前置验证规则(用于后台动态添加验证规则)
*/
prepositiveRules?: FormItemRule[]
/**
* 可选项数组
*/
optionArr?: OptionType[]
/**
* 占位符
*/
placeholder?: string
/**
* 表单项自定义props
*/
customProps?: { [key: string]: unknown }
/**
* 表单项组件自定义事件
*
* @param {unknown} evtData 自定义事件的数据
*
*/
customEvt?: Record<string, (...args: any | undefined) => void>
/**
* 当前表单项是否需要显示. 默认:true
*/
needRender?: NeedRender
}
export type DynFormConfig<T extends DynFormData> = Record<string, FormItemConfig<T>>
export type NeedRenderFun = (formData: DynFormData) => boolean
export type NeedRender = NeedRenderFun | boolean
/**
* 动态项组件加载方法(该方法用于获取动态项组件实例)
*
* vite通过 import.meta.glob 方式获取
*
* 返回值map的key为动态项标识,value为动态项组件
*/
export type DynCompLoadMethod = () => Map<string, Component>
/**
* 表单项目组件公共props
*/
export interface DynFormItemCompProps {
/**
* 表单数据
*/
formData: DynFormData
/**
* 表单项字段
*/
prop: string
/**
* 表单项目值. 需定义为v-model
*/
value?: string
placeholder?: string
/**
* 可选列表。用于类似select的组件
*/
optionArr?: OptionType[]
}
/**
* 表单项标记有误
*/
interface FormItemMarkError {
/**
* 表单项标识
*/
field: string
/**
* 错误提示信息
*/
errorMsg: string
}
/**
* 表单标记有误信息
*/
type FormMarkErrors = Record<string, string | Record<string, string>>
普通动态表单
下拉选择值,控制关联文本可见性
下拉选择值,控制关联动态下拉选项
下拉选择值,控制日期范围验证规则
日期范围的动态验证规则如下:
日期范围表单项在下拉选择表单项无值时,非必填日期范围表单项在下拉选择表单项有值时,必填且开始日期必须在当前年的 1 月 15 日
主要交互逻辑如下:
下拉选择表单项改变时,则验证日期范围表单项下拉选择表单项清空时,则清除日期范围表单项的验证错误提示
后端控制表单项是否展示和必填
扩展:只读与可编辑切换, 恢复编辑前数据
扩展:标记有误
- 对表单项填写值进行标记有误
- 清除指定表单项的标记有误
- 取消编辑时恢复标记有误
- 对标记有误字段进行是否改为了不同值进行验证
动态表格有哪些东西是动态的
- 列是动态的
普通动态表格
爱好列使用了 formatter 进行了值显示格式化操作列通过自定义组件完成渲染,并支持 del 事件
扩展:动态表格结合的行编辑动态表单
扩展:标记有误
参考资料
zelda_player / eleme-plus-crud