共享 props
所有组件都可定义的 props
field
- 类型:
string - 默认:
-
当前选项提交给后端的字段(由于是对象形式配置的, 因此自动取对象的键, 不需要传递)
fields
- 类型:
string[] - 默认:
-
当前选项提交给后端的字段,优先级比 field 高,根据数组成员来匹配字段
点我查看示例
tsx
// 比如日期区间, 后端需要两个字段
// 按如下配置后, 提交时的 query 为 { beginDate: '2023-09-13', endDate: '2025-09-13' }
// 注意: 此时日期不能为必填项
defineOption({
date: {
t: 'date-picker',
type: 'daterange',
fields: ['beginDate', 'endDate'],
defaultValue: ['2023-09-13', '2025-09-13'],
},
});options
- 类型:
any[] - 默认:
-
给类似下拉框的组件传递的数据源, 如果是远程数据, 该选项不需要定义
getOptions
- 类型:
(callback, query, option) => void - 默认:
-
获取远程数据源提供给类似下拉框的组件
tips
如果传递的 getOptions 不是异步函数, callback 函数则必须执行, 否则 loading 不会变为 false, loading 逻辑请看下方的示例
点我查看 getOptions 的类型定义和示例(包含远程搜索)以及 loading 的逻辑
tsx
// loading 执行逻辑
// 调用 getOption 前, 先置为 true
// 如果 getOption 是异步函数, 等待异步函数执行完成后, 置为 false
// 非异步函数则等 callback 函数执行后, 置为 false
// 示例1: 远程搜索
defineOption({
operateType: {
t: 'select',
label: '操作类型',
remote: true,
async getOption(callback, query, { filterValue }) {
// 如果不存在搜索值, 直接返回
if (!filterValue) return callback([]);
// 获取远程数据
const res = await getRemoteOptions({ filterValue });
// 将远程数据传递进行
callback(res.status ? res.data : []);
},
},
});
// 示例2: 获取数据源后, 更新当前值并设置默认值
defineOption({
operateType: {
t: 'select',
label: '操作类型',
async getOption(callback, query, { search }) {
// 获取远程数据
const res = await getRemoteOptions();
// 将远程数据传递进行
callback(res.status ? res.data : []);
// 默认选中第 0 条数据, 并设置为默认值(无法被删除)
search(res.data[0].value, { updateDefaultValue: true });
},
},
});
/**
* getOptions 的类型定义
* @param {Function} callback 执行 callback 将数据传到内部
* @param {Record<string, any>} query 为当前字段集合
* @param {Record<string, any>} option 额外的配置项
*/
type getOptions = (
callback: (options: any[]) => void,
query: Record<string, any>,
option: Option
) => any | Promise<any>;
/** 额外的配置项 */
interface Option {
/** 用于下拉框等存在筛选值的组件 */
filterValue?: string;
/**
* 触发来源
* @enum {('initial'|'depend'|'other')} initial(初始化), depend(依赖项改变), other(其它, 比如主动执行或者远程搜索等)
*/
trigger: string;
/**
* 所有条件的数据源
* @enum {Record<string, Record<string, any>[]>}
*/
options: Record<string, any[]>;
/** 获取数据源后更改该选项的默认值 */
changeDefaultValue: (value: any) => this;
/** 获取数据源后更改该选项的初始值 */
changeInitialValue: (value: any) => this;
/**
* 仅改变内部的值, 不触发搜索事件(如果是实时搜索, 则会触发搜索事件)
* @param {*} value 需改变的值
* @param {object} [option]
* @param {boolean} [option.updateInitialValue] 是否将该值设为初始值
* @param {boolean} [option.updateDefaultValue] 是否将该值设为默认值
*/
change: (value: any, option?: Partial<Record<'updateInitialValue' | 'updateDefaultValue', boolean>>) => this;
/**
* 改变内部的值, 并触发搜索事件
* @param {*} value 需改变的值
* @param {object} [option]
* @param {boolean} [option.updateInitialValue] 是否将该值设为初始值
* @param {boolean} [option.updateDefaultValue] 是否将该值设为默认值
*/
search: (value: T, option?: Partial<Record<'updateInitialValue' | 'updateDefaultValue', boolean>>) => this;
}initialValue
- 类型:
string|number|boolean|any[]|Record<string, any>|() => any - 默认:
-
初始或重置时设置的值, 优先级高于 defaultValue, 可以被清空
defaultValue
- 类型:
string|number|boolean|any[]|Record<string, any>|() => any - 默认:
-
默认值, 当对应字段的值为空值时, 会用该值替换
hide
- 类型:
boolean|(option: { query: Record<string, any> }) => boolean - 默认:
false
隐藏组件
depend
- 类型:
boolean - 默认:
false
是否依赖其它字段, 其它字段发生变化时默认会重置本身的值
dependFields
- 类型:
string|string[] - 默认:
-
depend 为真时, 依赖的字段
resetByDependValueChange
- 类型:
boolean|(query: Record<string, any>) => boolean - 默认:
true
depend 为真时, 依赖字段发生变化后是否重置本身的值
dependWatchOption
- 类型:
Record<string, any> - 默认:
-
依赖字段监听的配置项(vue 的 WatchOptions)
optionsDepend
- 类型:
boolean - 默认:
-
是否依赖其它字段的数据源 - 依赖字段的数据源发生变动时触发自身的 getOptions
optionsDependFields
- 类型:
string|string[] - 默认:
dependFields
数据源依赖字段, 默认取 dependFields 字段
validator
- 类型:
(query: Record<string, any>) => any | Promise<any> - 默认:
-
搜索事件触发时调用的校验函数, 返回值为真且是字符串时会执行 HForm 组件的 toast 函数
hooks
- 类型:
Hooks - 默认:
-
组件项的钩子函数, 可通过钩子监听组件生命周期等信息
查看 Hooks 类型以及使用方法
tsx
import { onMounted } from 'vue';
// 示例:
defineOption({
operateType: {
t: 'select',
label: '操作类型',
options: [
{ label: '新增', value: 'add', children: [{ label: '新增用户', value: 'add-user' }, { label: '新增菜单', value: 'add-menu' }] },
{ label: '编辑', value: 'edit', children: [{ label: '编辑角色', value: 'edit-role' }, { label: '编辑部门', value: 'edit-dept' }] }
],
},
operateSubType: {
t: 'select',
label: '操作子类型',
depend: true,
dependFields: 'operateType',
optionsDepend: true,
hooks: {
created() {
onMounted(console.log.bind(null, '下拉组件已渲染'));
},
dependChange({ plain, props }) {
const option = plain.wrapper.options.operateType.find((v) => v.value === props.query.operateType);
plain.remoteOption.value = option ? JSON.parse(JSON.stringify(option.children)) : [];
},
// 该方法是防止 operateType 赋值在前 options 异步获取值在后
// 导致 operateType 的 options 有值, 子选项的 options 却为空
optionsDependChange({ plain, props }) {
const option = plain.wrapper.options.operateType.find((v) => v.value === props.query.operateType);
plain.remoteOption.value = option ? JSON.parse(JSON.stringify(option.children)) : [];
},
},
},
});
interface Hooks {
/** 组件创建后执行, 可在此函数内监听 vue 组件的生命周期 */
created?: (option: {
plain: PlainReturnValue;
props: Record<string, any>;
}) => void;
/** 依赖值发生变动后执行 */
dependChange?: (option: {
plain: PlainReturnValue;
props: Record<string, any>;
}) => void;
/** 依赖数据源发生变化后执行 */
optionsDependChange?: (option: {
plain: PlainReturnValue;
props: Record<string, any>;
}) => void;
}ts
/** usePlain 的返回值 */
export interface PlainReturnValue {
/** 覆盖 props 的最新的值(defaultValue, initialValue) */
coverProps: Record<'defaultValue' | 'initialValue', any>;
/** HForm 暴露给组件的选项 */
wrapper: WrapperProvideValue;
/** 在特定时机中 HForm 会调用该选项下的方法 */
option: CommonMethod;
/** 数据加载状态 */
loading: Ref<boolean>;
/** 可主动获取远程数据 */
getOptions: (trigger: 'initial' | 'depend' | 'other', option?: {
/** 筛选值 */
filterValue?: string;
}) => Promise<void>;
/** 当前组件的值 */
checked: Ref<any>;
/** 获取当前组件提交给后端的值 */
getQuery: () => Record<string, any>;
/** 远程数据(getOptions 返回的数据) */
remoteOption: Ref<Record<string, any>[]>;
/** 优先返回 remoteOption, 其次返回外部传递的 options */
finalOption: ComputedRef<Record<string, any>[]>;
/** 是否隐藏组件 */
insetHide: ComputedRef<boolean>;
/** 更新值但不触发外部的搜索事件 */
updateCheckedValue: (value: any) => void;
/**
* 更新值并根据 HForm realtime 状态判断
* - realtime: true 则触发搜索事件
* - realtime: false 则仅更新值(等同于 updateCheckedValue 函数)
*/
change: (value: any) => void;
/** 等同于 updateCheckedValue, 只是可以选择不传值(用来兼容低版本) */
trigger: (value?: any) => void;
/** 触发搜索事件 */
search: () => void;
/** 重置 */
reset: () => void;
/** 传递给 HForm 的 readonly 属性 */
globalReadonly: Ref<boolean>;
/** 传递给 HForm 的 disabled 属性 */
globalDisabled: Ref<boolean>;
}
/** 组件提供给 HForm 的选项 */
export interface CommonMethod {
/** 重置 */
reset: () => void;
/** 更新 HForm 中 query 的值 */
updateWrapperQuery: () => void;
/** 校验方法 */
validator?: (query: Record<string, string>) => Promise<any> | any;
/** 获取该组件拼接的参数 */
getQuery: () => Record<string, any>;
/** 在 watch 中 backfill 改变后, 需要执行回调 */
onChangeByBackfill?: () => void;
}
/** HForm 暴露给组件的选项 */
export interface WrapperProvideValue {
/** 表单是否只读 */
readonly?: Ref<boolean | undefined>;
/** 表单是否禁用 */
disabled?: Ref<boolean | undefined>;
/**
* 是否实时触发
*/
realtime: Ref<boolean | undefined>;
/**
* 子组件需主动注册组件, 否则不会生效
* @param {CommonMethod} config 提供父组件校验, 重置等方法
*
* @returns {() => void} 取消注册 - 默认会自动取消, 如果是异步任务内注册, 需自己手动取消
*/
register: (config: CommonMethod) => () => void;
/**
* 子组件通知父级更新 query 中的值 - 静默修改, 不触发搜索事件
* @param {string} field 更新的字段
* @param {*} value 更新的值
* @param {string} nativeField 原始提供的字段(不受 as, fields 等属性的影响)
*/
updateQueryValue: (field: string, value: any, nativeField: string) => void;
/**
* 子组件内部值发生了变动, 由父级决定是否触发搜索事件(实时搜索时需要区分这两种方式)
* @param {string | string[]} [tryFields] 比较 query[tryFields] 与 backfill[tryFields]是否一致, 不一致时才触发搜索
*/
insetSearch: (tryFields?: string | string[]) => void;
/**
* 提供给组件内部的直接触发到外部的搜索事件
*/
search: () => Promise<string | void>;
/** 删除内部无引用的字段 */
removeUnreferencedField: (field: string) => void;
/** 所有条件的 options 数据 */
options: Record<string, any[]>;
}emptyValue
- 类型:
string|number|boolean|null|undefined - 默认:
-
空值时提交的值
customGetQuery
- 类型:
(checkedValue: any, emptyToValue: (val: any, defaultValue: any) => any, props: Record<string, any>) => Record<string, any> - 默认:
-
自定义返回该配置项的 query 信息, 默认会根据传递的 field 或者 fields 生成, 一般情况下用不到该函数