feat: 优化表单提示
parent
eeed362320
commit
17c695d065
|
|
@ -1,4 +1,5 @@
|
||||||
import { Form, FormInstance, FormItem } from "@arco-design/web-vue";
|
import { Form, FormInstance } from "@arco-design/web-vue";
|
||||||
|
import { useVModel } from "@vueuse/core";
|
||||||
import { PropType } from "vue";
|
import { PropType } from "vue";
|
||||||
import { FormContextKey } from "../core/useFormContext";
|
import { FormContextKey } from "../core/useFormContext";
|
||||||
import { useFormItems } from "../core/useFormItems";
|
import { useFormItems } from "../core/useFormItems";
|
||||||
|
|
@ -6,7 +7,6 @@ import { useFormModel } from "../core/useFormModel";
|
||||||
import { useFormRef } from "../core/useFormRef";
|
import { useFormRef } from "../core/useFormRef";
|
||||||
import { useFormSubmit } from "../core/useFormSubmit";
|
import { useFormSubmit } from "../core/useFormSubmit";
|
||||||
import { AnFormItem, IAnFormItem } from "./FormItem";
|
import { AnFormItem, IAnFormItem } from "./FormItem";
|
||||||
import { useVModel } from "@vueuse/core";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单组件
|
* 表单组件
|
||||||
|
|
@ -16,6 +16,12 @@ export const AnForm = defineComponent({
|
||||||
props: {
|
props: {
|
||||||
/**
|
/**
|
||||||
* 表单数据
|
* 表单数据
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* {
|
||||||
|
* id: undefined
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
model: {
|
model: {
|
||||||
type: Object as PropType<Recordable>,
|
type: Object as PropType<Recordable>,
|
||||||
|
|
@ -30,12 +36,24 @@ export const AnForm = defineComponent({
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 提交表单
|
* 提交表单
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* (model) => {
|
||||||
|
* return api.user.addUser(model)
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
submit: {
|
submit: {
|
||||||
type: [String, Function, Object] as PropType<IAnFormSubmit>,
|
type: [String, Function, Object] as PropType<IAnFormSubmit>,
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 传给Form组件的参数
|
* 传给Form组件的参数
|
||||||
|
* @exmaple
|
||||||
|
* ```ts
|
||||||
|
* {
|
||||||
|
* layout: 'vertical'
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
formProps: {
|
formProps: {
|
||||||
type: Object as IAnFormProps,
|
type: Object as IAnFormProps,
|
||||||
|
|
|
||||||
|
|
@ -59,14 +59,12 @@ export const AnFormItem = defineComponent({
|
||||||
if (Slot) {
|
if (Slot) {
|
||||||
return <Slot {...props} />;
|
return <Slot {...props} />;
|
||||||
}
|
}
|
||||||
|
const Setter = setterMap[props.item.setter as SetterType]?.setter as any;
|
||||||
const Setter = setterMap[props.item.setter as SetterType]?.render as any;
|
|
||||||
if (!Setter) {
|
if (!Setter) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Setter {...props.item.nodeProps} v-model={props.model[props.item.field]}>
|
<Setter {...props.item.setterProps} v-model={props.model[props.item.field]}>
|
||||||
{setterSlots.value}
|
{setterSlots.value}
|
||||||
</Setter>
|
</Setter>
|
||||||
);
|
);
|
||||||
|
|
@ -152,13 +150,19 @@ export type IAnFormItemBase = {
|
||||||
/**
|
/**
|
||||||
* 字段名
|
* 字段名
|
||||||
* @description 字段名唯一,支持特殊语法
|
* @description 字段名唯一,支持特殊语法
|
||||||
* @required
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* 'username'
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
field: string;
|
field: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标签
|
* 标签
|
||||||
* @example '昵称'
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* '昵称'
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
label?: string;
|
label?: string;
|
||||||
|
|
||||||
|
|
@ -170,19 +174,29 @@ export type IAnFormItemBase = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否可见
|
* 是否可见
|
||||||
* @example (model) => Boolean(model.id)
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* (props) => Boolean(props.model.id)
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
visible?: IAnFormItemBoolFn;
|
visible?: IAnFormItemBoolFn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否禁用
|
* 是否禁用
|
||||||
* @example (model) => Boolean(model.id)
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* (props) => Boolean(props.model.id)
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
disable?: IAnFormItemBoolFn;
|
disable?: IAnFormItemBoolFn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 选项
|
* 选项
|
||||||
* @description 适用于下拉框等组件
|
* @description 适用于下拉框等组件
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* [{ label: '方式1', value: 1 }]
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
options?: IAnFormItemOption[] | ((args: IAnFormItemFnProps) => IAnFormItemOption[] | Promise<IAnFormItemOption[]>);
|
options?: IAnFormItemOption[] | ((args: IAnFormItemFnProps) => IAnFormItemOption[] | Promise<IAnFormItemOption[]>);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
|
import { useVisible } from "@/hooks/useVisible";
|
||||||
import { Button, ButtonInstance, Modal } from "@arco-design/web-vue";
|
import { Button, ButtonInstance, Modal } from "@arco-design/web-vue";
|
||||||
import { PropType } from "vue";
|
import { PropType } from "vue";
|
||||||
import { IAnFormItem } from "./FormItem";
|
|
||||||
import { AnForm, IAnFormProps, IAnFormSubmit } from "./Form";
|
|
||||||
import { useModalTrigger } from "../core/useModalTrigger";
|
|
||||||
import { useModalSubmit } from "../core/useModalSubmit";
|
import { useModalSubmit } from "../core/useModalSubmit";
|
||||||
import { useVisible } from "@/hooks/useVisible";
|
import { useModalTrigger } from "../core/useModalTrigger";
|
||||||
|
import { AnForm, IAnFormProps, IAnFormSubmit } from "./Form";
|
||||||
|
import { IAnFormItem } from "./FormItem";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单组件
|
* 表单组件
|
||||||
|
|
@ -14,11 +14,11 @@ export const AnFormModal = defineComponent({
|
||||||
props: {
|
props: {
|
||||||
/**
|
/**
|
||||||
* 弹窗标题
|
* 弹窗标题
|
||||||
* @default '添加'
|
* @default '新增'
|
||||||
*/
|
*/
|
||||||
title: {
|
title: {
|
||||||
type: [String, Function] as PropType<ModalType>,
|
type: [String, Function] as PropType<ModalType>,
|
||||||
default: "添加",
|
default: "新增",
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 触发元素
|
* 触发元素
|
||||||
|
|
|
||||||
|
|
@ -4,24 +4,42 @@ export type SetterMap = typeof setterMap;
|
||||||
|
|
||||||
export type SetterType = keyof SetterMap;
|
export type SetterType = keyof SetterMap;
|
||||||
|
|
||||||
export type SetterItem = {
|
export type SetterItemMap = {
|
||||||
[key in SetterType]: Partial<
|
[key in SetterType]: {
|
||||||
Omit<SetterMap[key], 'setter'> & {
|
|
||||||
/**
|
/**
|
||||||
* 控件类型
|
* 控件类型
|
||||||
* @example 'input'
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* 'input'
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
setter: key;
|
setter?: key;
|
||||||
/**
|
|
||||||
* 控件插槽
|
|
||||||
*/
|
|
||||||
setterSlots: Recordable;
|
|
||||||
/**
|
/**
|
||||||
* 控件参数
|
* 控件参数
|
||||||
|
* @example
|
||||||
|
* ```tsx
|
||||||
|
* { type: "password" }
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
setterProps: Recordable;
|
setterProps?: SetterMap[key]['setterProps'];
|
||||||
}
|
/**
|
||||||
>;
|
* 控件插槽
|
||||||
}[SetterType];
|
* @example
|
||||||
|
* ```tsx
|
||||||
|
* {
|
||||||
|
* help: (props) => {
|
||||||
|
* return <span>
|
||||||
|
* {props.item.label}
|
||||||
|
* </span>
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
setterSlots?: SetterMap[key]['setterSlots'];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SetterItem = SetterItemMap[SetterType];
|
||||||
|
|
||||||
export { setterMap };
|
export { setterMap };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ export function useFormItems(items: Ref<IAnFormItem[]>, model: Ref<Recordable>)
|
||||||
const getItemOptions = (field: string) => {
|
const getItemOptions = (field: string) => {
|
||||||
const item = getItem(field);
|
const item = getItem(field);
|
||||||
if (item) {
|
if (item) {
|
||||||
return (item.nodeProps as any)?.options;
|
return (item.setterProps as any)?.options;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,17 @@
|
||||||
import { FormItem, useItems } from "./useItems";
|
|
||||||
import { AnForm, IAnForm } from "../components/Form";
|
import { AnForm, IAnForm } from "../components/Form";
|
||||||
|
import { FormItem, useItems } from "./useItems";
|
||||||
|
|
||||||
export type FormUseOptions = Partial<Omit<IAnForm, "items">> & {
|
export type FormUseOptions = Partial<Omit<IAnForm, "items">> & {
|
||||||
/**
|
/**
|
||||||
* 表单项
|
* 表单项
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* [{
|
||||||
|
* field: 'name',
|
||||||
|
* label: '昵称',
|
||||||
|
* setter: 'input'
|
||||||
|
* }]
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
items?: FormItem[];
|
items?: FormItem[];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,49 @@
|
||||||
import { defaultsDeep, merge, omit } from "lodash-es";
|
import { defaultsDeep, merge, omit } from 'lodash-es';
|
||||||
import { Rule, useRules } from "./useRules";
|
import { IAnFormItem, IAnFormItemBase } from '../components/FormItem';
|
||||||
import { IAnFormItem } from "../components/FormItem";
|
import { SetterItem, setterMap } from '../components/FormSetter';
|
||||||
import { setterMap } from "../components/FormSetter";
|
import { Rule, useRules } from './useRules';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单项数据
|
* 表单项数据
|
||||||
*/
|
*/
|
||||||
export type FormItem = Omit<IAnFormItem, "rules"> & {
|
export type FormItem = Omit<IAnFormItemBase, 'rules'> &
|
||||||
|
SetterItem & {
|
||||||
/**
|
/**
|
||||||
* 默认值
|
* 默认值
|
||||||
* @example 1
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* '1'
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
value?: any;
|
value?: any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否必填
|
* 是否必填
|
||||||
* @default false
|
* @default
|
||||||
|
* ```ts
|
||||||
|
* false
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验规则
|
* 校验规则
|
||||||
* @example ['email']
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* ['email']
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
rules?: Rule[];
|
rules?: Rule[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const ITEM: Partial<FormItem> = {
|
const ITEM: Partial<FormItem> = {
|
||||||
setter: "input",
|
setter: 'input',
|
||||||
itemProps: {},
|
itemProps: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const SUBMIT_ITEM: FormItem = {
|
const SUBMIT_ITEM: FormItem = {
|
||||||
field: "id",
|
field: 'id',
|
||||||
setter: "submit",
|
setter: 'submit',
|
||||||
itemProps: {
|
itemProps: {
|
||||||
hideLabel: true,
|
hideLabel: true,
|
||||||
},
|
},
|
||||||
|
|
@ -46,19 +56,19 @@ export function useItems(list: FormItem[], model: Recordable, submit: boolean) {
|
||||||
for (const item of list) {
|
for (const item of list) {
|
||||||
let target: any = defaultsDeep({}, ITEM);
|
let target: any = defaultsDeep({}, ITEM);
|
||||||
|
|
||||||
if (!item.setter || typeof item.setter === "string") {
|
if (!item.setter || typeof item.setter === 'string') {
|
||||||
const defaults = setterMap[item.setter ?? "input"];
|
const defaults = setterMap[item.setter ?? 'input'];
|
||||||
if (defaults) {
|
if (defaults) {
|
||||||
defaultsDeep(target, defaults);
|
defaultsDeep(target, defaults);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.setter === "submit") {
|
if (item.setter === 'submit') {
|
||||||
target = merge(target, SUBMIT_ITEM);
|
target = merge(target, SUBMIT_ITEM);
|
||||||
hasSubmit = true;
|
hasSubmit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
target = merge(target, omit(item, ["required", "rules"]));
|
target = merge(target, omit(item, ['required', 'rules']));
|
||||||
|
|
||||||
const rules = useRules(item);
|
const rules = useRules(item);
|
||||||
if (rules) {
|
if (rules) {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
import { Cascader, CascaderInstance } from "@arco-design/web-vue";
|
import { Cascader, CascaderInstance } from '@arco-design/web-vue';
|
||||||
import { initOptions } from "../utils/initOptions";
|
import { initOptions } from '../utils/initOptions';
|
||||||
|
import { defineSetter } from './util';
|
||||||
|
|
||||||
type Props = CascaderInstance["$props"];
|
type CascaderProps = CascaderInstance['$props'];
|
||||||
|
|
||||||
export default {
|
type CascaderSlots = 'label' | 'prefix' | 'arrowIcon' | 'loadingIcon' | 'searchIcon' | 'empty' | 'option';
|
||||||
render: Cascader,
|
|
||||||
init: initOptions,
|
export default defineSetter<CascaderProps, CascaderSlots>({
|
||||||
nodeProps: {
|
setter: Cascader,
|
||||||
placeholder: "请选择",
|
setterProps: {
|
||||||
|
placeholder: '请选择',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
expandTrigger: "hover",
|
expandTrigger: 'hover',
|
||||||
} as Props,
|
},
|
||||||
};
|
onSetup: initOptions as any,
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
export default {
|
import { defineSetter } from './util';
|
||||||
render: () => {
|
|
||||||
return "1";
|
export default defineSetter<{ a: number }, '11'>({
|
||||||
},
|
setter: () => '1',
|
||||||
nodeProps: {},
|
});
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
import { DatePicker, DatePickerInstance } from "@arco-design/web-vue";
|
import { DatePicker, DatePickerInstance } from '@arco-design/web-vue';
|
||||||
|
import { defineSetter } from './util';
|
||||||
|
|
||||||
type Props = DatePickerInstance["$props"];
|
type DateProps = DatePickerInstance['$props'];
|
||||||
|
|
||||||
export default {
|
type DateSlots = 'prefix' | 'suffixIcon' | 'iconNextDouble' | 'iconPrevDouble' | 'iconNext' | 'iconPrev' | 'cell' | 'extra';
|
||||||
render: DatePicker,
|
|
||||||
nodeProps: {
|
export default defineSetter<DateProps, DateSlots>({
|
||||||
placeholder: "请选择",
|
setter: DatePicker,
|
||||||
|
setterProps: {
|
||||||
|
placeholder: '请选择',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
} as Props,
|
} as any,
|
||||||
};
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import { RangePicker, RangePickerInstance } from "@arco-design/web-vue";
|
import { RangePicker, RangePickerInstance } from '@arco-design/web-vue';
|
||||||
|
import { defineSetter } from './util';
|
||||||
|
|
||||||
type Props = RangePickerInstance["$props"];
|
type RangeProps = RangePickerInstance['$props'];
|
||||||
|
|
||||||
export default {
|
type RangeSlots = "1";
|
||||||
render: RangePicker,
|
|
||||||
nodeProps: {
|
export default defineSetter<RangeProps, RangeSlots>({
|
||||||
|
setter: RangePicker,
|
||||||
|
setterProps: {
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
} as Props,
|
},
|
||||||
};
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
import { Input, InputInstance } from "@arco-design/web-vue";
|
import { Input, InputInstance } from '@arco-design/web-vue';
|
||||||
|
import { defineSetter } from './util';
|
||||||
|
|
||||||
type Props = InputInstance["$props"];
|
type InputProps = InputInstance['$props'];
|
||||||
|
|
||||||
export default {
|
type InputSlots = "2";
|
||||||
render: Input,
|
|
||||||
nodeProps: {
|
export default defineSetter<InputProps, InputSlots>({
|
||||||
placeholder: "请输入",
|
setter: Input,
|
||||||
|
setterProps: {
|
||||||
|
placeholder: '请输入',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
} as Props,
|
},
|
||||||
};
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
import { InputInstance, InputNumber, InputNumberInstance } from "@arco-design/web-vue";
|
import { InputInstance, InputNumber, InputNumberInstance } from '@arco-design/web-vue';
|
||||||
|
import { defineSetter } from './util';
|
||||||
|
|
||||||
type Props = InputInstance["$props"] & InputNumberInstance["$props"];
|
type NumberProps = InputInstance['$props'] | InputNumberInstance['$props'];
|
||||||
|
|
||||||
export default {
|
type NumberSlots = "3";
|
||||||
render: InputNumber,
|
|
||||||
nodeProps: {
|
export default defineSetter<NumberProps, NumberSlots>({
|
||||||
placeholder: "请输入",
|
setter: InputNumber,
|
||||||
|
setterProps: {
|
||||||
|
placeholder: '请输入',
|
||||||
defaultValue: 0,
|
defaultValue: 0,
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
} as Props,
|
},
|
||||||
};
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import { InputInstance, InputPassword, InputPasswordInstance } from "@arco-design/web-vue";
|
import { InputInstance, InputPassword, InputPasswordInstance } from '@arco-design/web-vue';
|
||||||
|
import { defineSetter } from './util';
|
||||||
|
|
||||||
type Props = InputInstance["$props"] & InputPasswordInstance["$props"];
|
type PasswordProps = InputInstance['$props'] & InputPasswordInstance['$props'];
|
||||||
|
|
||||||
export default {
|
type PasswordSlots = "4";
|
||||||
render: InputPassword,
|
|
||||||
nodeProps: {
|
export default defineSetter<PasswordProps, PasswordSlots>({
|
||||||
placeholder: "请输入",
|
setter: InputPassword,
|
||||||
} as Props,
|
setterProps: {
|
||||||
};
|
placeholder: '请输入',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
import { InputInstance, InputSearch, InputSearchInstance } from "@arco-design/web-vue";
|
import { InputInstance, InputSearch, InputSearchInstance } from '@arco-design/web-vue';
|
||||||
|
import { defineSetter } from './util';
|
||||||
|
|
||||||
type Props = InputInstance["$props"] & InputSearchInstance["$props"];
|
type SearchProps = InputInstance['$props'] & InputSearchInstance['$props'];
|
||||||
|
|
||||||
export default {
|
type SearchSlots = "5";
|
||||||
render: InputSearch,
|
|
||||||
nodeProps: {
|
export default defineSetter<SearchProps, SearchSlots>({
|
||||||
placeholder: "请输入",
|
setter: InputSearch,
|
||||||
|
setterProps: {
|
||||||
|
placeholder: '请输入',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
} as Props,
|
},
|
||||||
};
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,18 @@
|
||||||
import { Select, SelectInstance, SelectOptionData } from "@arco-design/web-vue";
|
import { Select, SelectInstance } from '@arco-design/web-vue';
|
||||||
import { initOptions } from "../utils/initOptions";
|
import { initOptions } from '../utils/initOptions';
|
||||||
|
import { defineSetter } from './util';
|
||||||
|
|
||||||
export default {
|
type SelectProps = SelectInstance['$props'];
|
||||||
render: Select,
|
|
||||||
init: initOptions,
|
type SelectSlots = "6";
|
||||||
nodeProps: {
|
|
||||||
placeholder: "请选择",
|
export default defineSetter<SelectProps, SelectSlots>({
|
||||||
|
setter: Select,
|
||||||
|
onSetup: initOptions as any,
|
||||||
|
setterProps: {
|
||||||
|
placeholder: '请选择',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
allowSearch: true,
|
allowSearch: true,
|
||||||
options: [],
|
options: [],
|
||||||
} as SelectInstance["$props"],
|
},
|
||||||
options: [] as SelectOptionData[] | ((arg: any) => Recordable[] | Promise<Recordable[]>) | undefined,
|
});
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import { Button } from "@arco-design/web-vue";
|
import { Button } from "@arco-design/web-vue";
|
||||||
import { FormContextKey } from "../core/useFormContext";
|
import { FormContextKey } from "../core/useFormContext";
|
||||||
|
import { defineSetter } from "./util";
|
||||||
|
|
||||||
export default {
|
export default defineSetter<{ a1?: number }, "10">({
|
||||||
render() {
|
setter() {
|
||||||
const { loading, submitForm, resetModel } = inject(FormContextKey)!;
|
const { loading, submitForm, resetModel } = inject(FormContextKey)!;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
@ -15,5 +16,5 @@ export default {
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
nodeProps: {},
|
setterProps: {},
|
||||||
};
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
import { InputInstance, Textarea, TextareaInstance } from "@arco-design/web-vue";
|
import { InputInstance, Textarea, TextareaInstance } from '@arco-design/web-vue';
|
||||||
|
import { defineSetter } from './util';
|
||||||
|
|
||||||
type Props = InputInstance["$props"] & TextareaInstance["$props"];
|
type TextareaProps = InputInstance['$props'] & TextareaInstance['$props'];
|
||||||
|
|
||||||
export default {
|
type TextareaSlots = "7";
|
||||||
render: Textarea,
|
|
||||||
nodeProps: {
|
export default defineSetter<TextareaProps, TextareaSlots>({
|
||||||
placeholder: "请输入",
|
setter: Textarea,
|
||||||
|
setterProps: {
|
||||||
|
placeholder: '请输入',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
} as Props,
|
},
|
||||||
};
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import { TimePicker, TimePickerInstance } from "@arco-design/web-vue";
|
import { TimePicker, TimePickerInstance } from '@arco-design/web-vue';
|
||||||
|
import { defineSetter } from './util';
|
||||||
|
|
||||||
type Props = TimePickerInstance["$props"];
|
type TimeProps = TimePickerInstance['$props'];
|
||||||
|
|
||||||
export default {
|
type TimeSlots = "8";
|
||||||
render: TimePicker,
|
|
||||||
nodeProps: {
|
export default defineSetter<TimeProps, TimeSlots>({
|
||||||
|
setter: TimePicker,
|
||||||
|
setterProps: {
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
} as Props,
|
},
|
||||||
};
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,17 @@
|
||||||
import { TreeSelect, TreeSelectInstance } from "@arco-design/web-vue";
|
import { TreeSelect, TreeSelectInstance } from '@arco-design/web-vue';
|
||||||
import { initOptions } from "../utils/initOptions";
|
import { initOptions } from '../utils/initOptions';
|
||||||
|
import { defineSetter } from './util';
|
||||||
|
|
||||||
type Props = TreeSelectInstance["$props"];
|
type TreeSelectProps = TreeSelectInstance['$props'];
|
||||||
|
|
||||||
export default {
|
type TreeSelectSlots = "9";
|
||||||
render: TreeSelect,
|
|
||||||
init: (arg: any) => initOptions(arg, "data"),
|
export default defineSetter<TreeSelectProps, TreeSelectSlots>({
|
||||||
nodeProps: {
|
setter: TreeSelect,
|
||||||
placeholder: "请选择",
|
onSetup: (arg: any) => initOptions(arg, 'data') as any,
|
||||||
|
setterProps: {
|
||||||
|
placeholder: '请选择',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
allowSearch: true,
|
allowSearch: true,
|
||||||
options: [],
|
},
|
||||||
} as Props,
|
});
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
import cascader from "./Cascader";
|
import cascader from './Cascader';
|
||||||
import custom from "./Custom";
|
import custom from './Custom';
|
||||||
import date from "./Date";
|
import date from './Date';
|
||||||
import input from "./Input";
|
import dateRange from './DateRange';
|
||||||
import number from "./Number";
|
import input from './Input';
|
||||||
import password from "./Password";
|
import number from './Number';
|
||||||
import search from "./Search";
|
import password from './Password';
|
||||||
import select from "./Select";
|
import search from './Search';
|
||||||
import submit from "./Submit";
|
import select from './Select';
|
||||||
import textarea from "./Textarea";
|
import submit from './Submit';
|
||||||
import time from "./Time";
|
import textarea from './Textarea';
|
||||||
import treeSelect from "./TreeSelect";
|
import time from './Time';
|
||||||
import dateRange from "./DateRange";
|
import treeSelect from './TreeSelect';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
input,
|
input,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { Component } from 'vue';
|
||||||
|
import { IAnFormItemBase, IAnFormItemSlot } from '../components/FormItem';
|
||||||
|
|
||||||
|
export interface ItemSetter<P extends object, S extends string> {
|
||||||
|
/**
|
||||||
|
* 输入组件
|
||||||
|
*/
|
||||||
|
setter: Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入组件参数
|
||||||
|
*/
|
||||||
|
setterProps?: P;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间插槽
|
||||||
|
*/
|
||||||
|
setterSlots?: {
|
||||||
|
/**
|
||||||
|
* 控件插槽
|
||||||
|
* @example
|
||||||
|
* ```tsx
|
||||||
|
* (props) => {
|
||||||
|
* return <span>{props.item.label}</span>
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
[key in S]?: IAnFormItemSlot;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化钩子
|
||||||
|
*/
|
||||||
|
onSetup?: (model: Recordable, item: IAnFormItemBase, items: IAnFormItemBase[]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function defineSetter<P extends object, S extends string>(setter: ItemSetter<P, S>) {
|
||||||
|
return setter;
|
||||||
|
}
|
||||||
|
|
@ -1,27 +1,26 @@
|
||||||
import { Component } from "vue";
|
import { Component } from 'vue';
|
||||||
import { IAnFormItem, IAnFormItemBase } from "../components/FormItem";
|
import { IAnFormItemBase, IAnFormItemSlot } from '../components/FormItem';
|
||||||
|
|
||||||
interface Setter<T extends Component, P = T extends new (...args: any) => any ? InstanceType<T>["$props"] : any> {
|
export interface ItemSetter<P extends object, S extends string> {
|
||||||
/**
|
/**
|
||||||
* 输入组件
|
* 输入组件
|
||||||
*/
|
*/
|
||||||
component: T;
|
setter: Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输入组件参数
|
* 输入组件参数
|
||||||
*/
|
*/
|
||||||
componentProps?: P;
|
setterProps?: P;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间插槽
|
||||||
|
*/
|
||||||
|
setterSlots?: {
|
||||||
|
[key in S]?: IAnFormItemSlot;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化钩子
|
* 初始化钩子
|
||||||
* @param model 表单数据
|
|
||||||
* @param item 表单项
|
|
||||||
* @param items 表单项列表
|
|
||||||
* @returns
|
|
||||||
*/
|
*/
|
||||||
onSetup?: (model: Recordable, item: IAnFormItemBase, items: IAnFormItemBase[]) => void;
|
onSetup?: (model: Recordable, item: IAnFormItemBase, items: IAnFormItemBase[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function defineSetter<T extends Component>(options: Setter<T>): Setter<T> {
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ const { component: UpForm, model: emodel } = useForm({
|
||||||
{
|
{
|
||||||
field: 'xsa',
|
field: 'xsa',
|
||||||
label: '动态渲染',
|
label: '动态渲染',
|
||||||
setter: 'input',
|
setter: 'cascader',
|
||||||
visible: props => props.model.id,
|
visible: props => props.model.id,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -93,7 +93,7 @@ const { component: UpForm, model: emodel } = useForm({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
nodeProps: {
|
setterProps: {
|
||||||
valueKey: 'value',
|
valueKey: 'value',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue