mirror of
https://github.com/vbenjs/vben-admin-thin-next.git
synced 2025-02-02 18:08:40 +08:00
refactor(form): enhanced form customization and dynamic capabilities
This commit is contained in:
parent
3f78b5aa0c
commit
1d45617e4a
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
- 重构 hook,引入 `@vueuse`,删除其中已有的`hook`,优化现有的 hook
|
- 重构 hook,引入 `@vueuse`,删除其中已有的`hook`,优化现有的 hook
|
||||||
- `useEvent` 更名->`useEventListener`
|
- `useEvent` 更名->`useEventListener`
|
||||||
|
- 表单`ComponentType`删除 `SelectOptGroup`,`SelectOption`,`Transfer`,`Radio`,四个类型。修改`RadioButtonGroup`组件
|
||||||
|
|
||||||
### ✨ Features
|
### ✨ Features
|
||||||
|
|
||||||
@ -12,10 +13,15 @@
|
|||||||
- 新增菜单及顶栏颜色选择配色
|
- 新增菜单及顶栏颜色选择配色
|
||||||
- 增加示例结果页
|
- 增加示例结果页
|
||||||
|
|
||||||
|
### ⚡ Wip
|
||||||
|
|
||||||
|
- 上传组件(未完成,测试中...)
|
||||||
|
|
||||||
### ⚡ Performance Improvements
|
### ⚡ Performance Improvements
|
||||||
|
|
||||||
- 优化 settingDrawer 代码
|
- 优化 settingDrawer 代码
|
||||||
- 优化多标签页切换速度
|
- 优化多标签页切换速度
|
||||||
|
- 增加表单自定义及动态能力
|
||||||
|
|
||||||
### 🐛 Bug Fixes
|
### 🐛 Bug Fixes
|
||||||
|
|
||||||
@ -23,6 +29,7 @@
|
|||||||
- 修复登录过期后重新登录未跳转原来页面的
|
- 修复登录过期后重新登录未跳转原来页面的
|
||||||
- 修复 window 系统动态引入错误
|
- 修复 window 系统动态引入错误
|
||||||
- 修复页面类型错误
|
- 修复页面类型错误
|
||||||
|
- 修复表单 switch 和 checkBox 单独使用报错
|
||||||
|
|
||||||
## 2.0.0-rc.9 (2020-11-9)
|
## 2.0.0-rc.9 (2020-11-9)
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
<template v-for="schema in getSchema" :key="schema.field">
|
<template v-for="schema in getSchema" :key="schema.field">
|
||||||
<FormItem
|
<FormItem
|
||||||
:tableAction="tableAction"
|
:tableAction="tableAction"
|
||||||
|
:formActionType="formActionType"
|
||||||
:schema="schema"
|
:schema="schema"
|
||||||
:formProps="getProps"
|
:formProps="getProps"
|
||||||
:allDefaultValues="defaultValueRef"
|
:allDefaultValues="defaultValueRef"
|
||||||
@ -164,7 +165,7 @@
|
|||||||
propsRef.value = mergeProps;
|
propsRef.value = mergeProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
const methods: Partial<FormActionType> = {
|
const formActionType: Partial<FormActionType> = {
|
||||||
getFieldsValue,
|
getFieldsValue,
|
||||||
setFieldsValue,
|
setFieldsValue,
|
||||||
resetFields,
|
resetFields,
|
||||||
@ -179,7 +180,7 @@
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initDefault();
|
initDefault();
|
||||||
emit('register', methods);
|
emit('register', formActionType);
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -191,7 +192,8 @@
|
|||||||
getProps,
|
getProps,
|
||||||
formElRef,
|
formElRef,
|
||||||
getSchema,
|
getSchema,
|
||||||
...methods,
|
formActionType,
|
||||||
|
...formActionType,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { PropType } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
import type { FormProps } from './types/form';
|
import type { FormActionType, FormProps } from './types/form';
|
||||||
import type { FormSchema } from './types/form';
|
import type { FormSchema } from './types/form';
|
||||||
import type { ValidationRule } from 'ant-design-vue/lib/form/Form';
|
import type { ValidationRule } from 'ant-design-vue/lib/form/Form';
|
||||||
import type { TableActionType } from '/@/components/Table';
|
import type { TableActionType } from '/@/components/Table';
|
||||||
@ -41,6 +41,9 @@ export default defineComponent({
|
|||||||
tableAction: {
|
tableAction: {
|
||||||
type: Object as PropType<TableActionType>,
|
type: Object as PropType<TableActionType>,
|
||||||
},
|
},
|
||||||
|
formActionType: {
|
||||||
|
type: Object as PropType<FormActionType>,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
setup(props, { slots }) {
|
setup(props, { slots }) {
|
||||||
const itemLabelWidthRef = useItemLabelWidth(toRef(props, 'schema'), toRef(props, 'formProps'));
|
const itemLabelWidthRef = useItemLabelWidth(toRef(props, 'schema'), toRef(props, 'formProps'));
|
||||||
@ -61,12 +64,12 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const getComponentsPropsRef = computed(() => {
|
const getComponentsPropsRef = computed(() => {
|
||||||
const { schema, tableAction, formModel } = props;
|
const { schema, tableAction, formModel, formActionType } = props;
|
||||||
const { componentProps = {} } = schema;
|
const { componentProps = {} } = schema;
|
||||||
if (!isFunction(componentProps)) {
|
if (!isFunction(componentProps)) {
|
||||||
return componentProps;
|
return componentProps;
|
||||||
}
|
}
|
||||||
return componentProps({ schema, tableAction, formModel }) || {};
|
return componentProps({ schema, tableAction, formModel, formActionType }) || {};
|
||||||
});
|
});
|
||||||
|
|
||||||
const getDisableRef = computed(() => {
|
const getDisableRef = computed(() => {
|
||||||
@ -179,17 +182,27 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderComponent() {
|
function renderComponent() {
|
||||||
const { renderComponentContent, component, field, changeEvent = 'change' } = props.schema;
|
const {
|
||||||
|
renderComponentContent,
|
||||||
|
component,
|
||||||
|
field,
|
||||||
|
changeEvent = 'change',
|
||||||
|
valueField,
|
||||||
|
} = props.schema;
|
||||||
|
|
||||||
const isCheck = component && ['Switch'].includes(component);
|
const isCheck = component && ['Switch', 'Checkbox'].includes(component);
|
||||||
|
|
||||||
const eventKey = `on${upperFirst(changeEvent)}`;
|
const eventKey = `on${upperFirst(changeEvent)}`;
|
||||||
|
|
||||||
const on = {
|
const on = {
|
||||||
[eventKey]: (e: any) => {
|
[eventKey]: (e: any) => {
|
||||||
if (propsData[eventKey]) {
|
if (propsData[eventKey]) {
|
||||||
propsData[eventKey](e);
|
propsData[eventKey](e);
|
||||||
}
|
}
|
||||||
(props.formModel as any)[field] = e && e.target ? e.target.value : e;
|
|
||||||
|
const target = e ? e.target : null;
|
||||||
|
const value = target ? (isCheck ? target.checked : target.value) : e;
|
||||||
|
(props.formModel as any)[field] = value;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const Comp = componentMap.get(component);
|
const Comp = componentMap.get(component);
|
||||||
@ -215,17 +228,20 @@ export default defineComponent({
|
|||||||
propsData.codeField = field;
|
propsData.codeField = field;
|
||||||
propsData.formValues = unref(getValuesRef);
|
propsData.formValues = unref(getValuesRef);
|
||||||
const bindValue = {
|
const bindValue = {
|
||||||
[isCheck ? 'checked' : 'value']: handleValue(component, field),
|
[valueField || (isCheck ? 'checked' : 'value')]: handleValue(component, field),
|
||||||
};
|
};
|
||||||
if (!renderComponentContent) {
|
if (!renderComponentContent) {
|
||||||
return <Comp {...propsData} {...on} {...bindValue} />;
|
return <Comp {...propsData} {...on} {...bindValue} />;
|
||||||
}
|
}
|
||||||
|
const compSlot = isFunction(renderComponentContent)
|
||||||
|
? { ...renderComponentContent(unref(getValuesRef)) }
|
||||||
|
: {
|
||||||
|
default: () => renderComponentContent,
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Comp {...propsData} {...on} {...bindValue}>
|
<Comp {...propsData} {...on} {...bindValue}>
|
||||||
{{
|
{compSlot}
|
||||||
...renderComponentContent(unref(getValuesRef)),
|
|
||||||
}}
|
|
||||||
</Comp>
|
</Comp>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -249,7 +265,7 @@ export default defineComponent({
|
|||||||
const { colon } = props.formProps;
|
const { colon } = props.formProps;
|
||||||
const getContent = () => {
|
const getContent = () => {
|
||||||
return slot
|
return slot
|
||||||
? getSlot(slots, slot)
|
? getSlot(slots, slot, unref(getValuesRef))
|
||||||
: render
|
: render
|
||||||
? render(unref(getValuesRef))
|
? render(unref(getValuesRef))
|
||||||
: renderComponent();
|
: renderComponent();
|
||||||
@ -276,7 +292,7 @@ export default defineComponent({
|
|||||||
const { isIfShow, isShow } = getShow();
|
const { isIfShow, isShow } = getShow();
|
||||||
const getContent = () => {
|
const getContent = () => {
|
||||||
return colSlot
|
return colSlot
|
||||||
? getSlot(slots, colSlot)
|
? getSlot(slots, colSlot, unref(getValuesRef))
|
||||||
: renderColContent
|
: renderColContent
|
||||||
? renderColContent(unref(getValuesRef))
|
? renderColContent(unref(getValuesRef))
|
||||||
: renderItem();
|
: renderItem();
|
||||||
|
@ -14,8 +14,8 @@ import {
|
|||||||
Switch,
|
Switch,
|
||||||
TimePicker,
|
TimePicker,
|
||||||
TreeSelect,
|
TreeSelect,
|
||||||
Transfer,
|
|
||||||
} from 'ant-design-vue';
|
} from 'ant-design-vue';
|
||||||
|
import RadioButtonGroup from './components/RadioButtonGroup.vue';
|
||||||
|
|
||||||
import { ComponentType } from './types/index';
|
import { ComponentType } from './types/index';
|
||||||
|
|
||||||
@ -30,13 +30,13 @@ componentMap.set('InputNumber', InputNumber);
|
|||||||
componentMap.set('AutoComplete', AutoComplete);
|
componentMap.set('AutoComplete', AutoComplete);
|
||||||
|
|
||||||
componentMap.set('Select', Select);
|
componentMap.set('Select', Select);
|
||||||
componentMap.set('SelectOptGroup', Select.OptGroup);
|
// componentMap.set('SelectOptGroup', Select.OptGroup);
|
||||||
componentMap.set('SelectOption', Select.Option);
|
// componentMap.set('SelectOption', Select.Option);
|
||||||
componentMap.set('TreeSelect', TreeSelect);
|
componentMap.set('TreeSelect', TreeSelect);
|
||||||
componentMap.set('Transfer', Transfer);
|
// componentMap.set('Transfer', Transfer);
|
||||||
componentMap.set('Radio', Radio);
|
// componentMap.set('Radio', Radio);
|
||||||
componentMap.set('Switch', Switch);
|
componentMap.set('Switch', Switch);
|
||||||
componentMap.set('RadioButton', Radio.Button);
|
componentMap.set('RadioButtonGroup', RadioButtonGroup);
|
||||||
componentMap.set('RadioGroup', Radio.Group);
|
componentMap.set('RadioGroup', Radio.Group);
|
||||||
componentMap.set('Checkbox', Checkbox);
|
componentMap.set('Checkbox', Checkbox);
|
||||||
componentMap.set('CheckboxGroup', Checkbox.Group);
|
componentMap.set('CheckboxGroup', Checkbox.Group);
|
||||||
|
61
src/components/Form/src/components/RadioButtonGroup.vue
Normal file
61
src/components/Form/src/components/RadioButtonGroup.vue
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<template>
|
||||||
|
<RadioGroup v-bind="$attrs" v-model:value="valueRef" button-style="solid">
|
||||||
|
<template v-for="item in getOptions" :key="`${item.value}`">
|
||||||
|
<RadioButton :value="item.value"> {{ item.label }} </RadioButton>
|
||||||
|
</template>
|
||||||
|
</RadioGroup>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, ref, PropType, watch, unref, computed } from 'vue';
|
||||||
|
import { Radio } from 'ant-design-vue';
|
||||||
|
import {} from 'ant-design-vue/es/radio/Group';
|
||||||
|
import { isString } from '/@/utils/is';
|
||||||
|
|
||||||
|
type OptionsItem = { label: string; value: string; disabled?: boolean };
|
||||||
|
type RadioItem = string | OptionsItem;
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'RadioButtonGroup',
|
||||||
|
components: {
|
||||||
|
RadioGroup: Radio.Group,
|
||||||
|
RadioButton: Radio.Button,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: String as PropType<string>,
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Array as PropType<RadioItem[]>,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const valueRef = ref('');
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.value,
|
||||||
|
(v = '') => {
|
||||||
|
valueRef.value = v;
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => unref(valueRef),
|
||||||
|
() => {
|
||||||
|
emit('change', valueRef.value);
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
const getOptions = computed((): OptionsItem[] => {
|
||||||
|
const { options } = props;
|
||||||
|
if (!options || options.length === 0) return [];
|
||||||
|
const isStringArr = options.some((item) => isString(item));
|
||||||
|
if (!isStringArr) return options as OptionsItem[];
|
||||||
|
return options.map((item) => ({ label: item, value: item })) as OptionsItem[];
|
||||||
|
});
|
||||||
|
|
||||||
|
return { valueRef, getOptions };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
@ -7,6 +7,10 @@ import { TableActionType } from '../../../Table/src/types/table';
|
|||||||
|
|
||||||
export type FieldMapToTime = [string, [string, string], string?][];
|
export type FieldMapToTime = [string, [string, string], string?][];
|
||||||
|
|
||||||
|
export type Rule = RuleObject & {
|
||||||
|
trigger?: 'blur' | 'change' | ['change', 'blur'];
|
||||||
|
};
|
||||||
|
|
||||||
export interface RenderCallbackParams {
|
export interface RenderCallbackParams {
|
||||||
schema: FormSchema;
|
schema: FormSchema;
|
||||||
values: any;
|
values: any;
|
||||||
@ -98,7 +102,10 @@ export interface FormProps {
|
|||||||
export interface FormSchema {
|
export interface FormSchema {
|
||||||
// 字段名
|
// 字段名
|
||||||
field: string;
|
field: string;
|
||||||
|
// 内部值更改触发的事件名,默认 change
|
||||||
changeEvent?: string;
|
changeEvent?: string;
|
||||||
|
// v-model绑定的变量名 默认 value
|
||||||
|
valueField?: string;
|
||||||
// 标签名
|
// 标签名
|
||||||
label: string;
|
label: string;
|
||||||
// 文本右侧帮助文本
|
// 文本右侧帮助文本
|
||||||
@ -113,13 +120,18 @@ export interface FormSchema {
|
|||||||
component: ComponentType;
|
component: ComponentType;
|
||||||
// 组件参数
|
// 组件参数
|
||||||
componentProps?:
|
componentProps?:
|
||||||
| ((opt: { schema: FormSchema; tableAction: TableActionType; formModel: any }) => any)
|
| ((opt: {
|
||||||
|
schema: FormSchema;
|
||||||
|
tableAction: TableActionType;
|
||||||
|
formActionType: FormActionType;
|
||||||
|
formModel: any;
|
||||||
|
}) => any)
|
||||||
| object;
|
| object;
|
||||||
// 必填
|
// 必填
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
|
|
||||||
// 校验规则
|
// 校验规则
|
||||||
rules?: RuleObject[];
|
rules?: Rule[];
|
||||||
// 校验信息是否加入label
|
// 校验信息是否加入label
|
||||||
rulesMessageJoinLabel?: boolean;
|
rulesMessageJoinLabel?: boolean;
|
||||||
|
|
||||||
@ -146,7 +158,11 @@ export interface FormSchema {
|
|||||||
// 渲染 col内容,需要外层包裹 form-item
|
// 渲染 col内容,需要外层包裹 form-item
|
||||||
renderColContent?: (renderCallbackParams: RenderCallbackParams) => VNode | VNode[] | string;
|
renderColContent?: (renderCallbackParams: RenderCallbackParams) => VNode | VNode[] | string;
|
||||||
|
|
||||||
renderComponentContent?: (renderCallbackParams: RenderCallbackParams) => any;
|
renderComponentContent?:
|
||||||
|
| ((renderCallbackParams: RenderCallbackParams) => any)
|
||||||
|
| VNode
|
||||||
|
| VNode[]
|
||||||
|
| string;
|
||||||
|
|
||||||
// 自定义slot, 在 from-item内
|
// 自定义slot, 在 from-item内
|
||||||
slot?: string;
|
slot?: string;
|
||||||
@ -156,7 +172,7 @@ export interface FormSchema {
|
|||||||
|
|
||||||
dynamicDisabled?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean);
|
dynamicDisabled?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean);
|
||||||
|
|
||||||
dynamicRules?: (renderCallbackParams: RenderCallbackParams) => RuleObject[];
|
dynamicRules?: (renderCallbackParams: RenderCallbackParams) => Rule[];
|
||||||
}
|
}
|
||||||
export interface HelpComponentProps {
|
export interface HelpComponentProps {
|
||||||
maxWidth: string;
|
maxWidth: string;
|
||||||
|
@ -93,8 +93,8 @@ export type ComponentType =
|
|||||||
| 'SelectOption'
|
| 'SelectOption'
|
||||||
| 'TreeSelect'
|
| 'TreeSelect'
|
||||||
| 'Transfer'
|
| 'Transfer'
|
||||||
| 'Radio'
|
// | 'Radio'
|
||||||
| 'RadioButton'
|
| 'RadioButtonGroup'
|
||||||
| 'RadioGroup'
|
| 'RadioGroup'
|
||||||
| 'Checkbox'
|
| 'Checkbox'
|
||||||
| 'CheckboxGroup'
|
| 'CheckboxGroup'
|
||||||
|
@ -87,7 +87,7 @@ export interface GetColumnsParams {
|
|||||||
export type SizeType = 'default' | 'middle' | 'small' | 'large';
|
export type SizeType = 'default' | 'middle' | 'small' | 'large';
|
||||||
|
|
||||||
export interface TableActionType {
|
export interface TableActionType {
|
||||||
reload: (opt?: FetchParams) => Promise<void>;
|
// reload: (opt?: FetchParams) => Promise<void>;
|
||||||
getSelectRows: () => any[];
|
getSelectRows: () => any[];
|
||||||
clearSelectedRowKeys: () => void;
|
clearSelectedRowKeys: () => void;
|
||||||
getSelectRowKeys: () => string[];
|
getSelectRowKeys: () => string[];
|
||||||
|
@ -38,10 +38,10 @@ const menu: MenuModule = {
|
|||||||
path: 'strength-meter',
|
path: 'strength-meter',
|
||||||
name: '密码强度组件',
|
name: '密码强度组件',
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
path: 'upload',
|
// path: 'upload',
|
||||||
name: '上传组件',
|
// name: '上传组件',
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
path: 'scroll',
|
path: 'scroll',
|
||||||
name: '滚动组件',
|
name: '滚动组件',
|
||||||
|
@ -4,10 +4,18 @@ const menu: MenuModule = {
|
|||||||
menu: {
|
menu: {
|
||||||
path: '/form',
|
path: '/form',
|
||||||
name: 'Form',
|
name: 'Form',
|
||||||
|
tag: {
|
||||||
|
type: 'warn',
|
||||||
|
dot: true,
|
||||||
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'basic',
|
path: 'basic',
|
||||||
name: '基础表单',
|
name: '基础表单',
|
||||||
|
tag: {
|
||||||
|
type: 'warn',
|
||||||
|
content: 'updated',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'useForm',
|
path: 'useForm',
|
||||||
@ -24,14 +32,26 @@ const menu: MenuModule = {
|
|||||||
{
|
{
|
||||||
path: 'ruleForm',
|
path: 'ruleForm',
|
||||||
name: '表单校验',
|
name: '表单校验',
|
||||||
|
tag: {
|
||||||
|
type: 'warn',
|
||||||
|
content: 'updated',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'dynamicForm',
|
path: 'dynamicForm',
|
||||||
name: '动态表单',
|
name: '动态表单',
|
||||||
|
tag: {
|
||||||
|
type: 'warn',
|
||||||
|
content: 'updated',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'customerForm',
|
path: 'customerForm',
|
||||||
name: '自定义组件',
|
name: '自定义组件',
|
||||||
|
tag: {
|
||||||
|
type: 'warn',
|
||||||
|
content: 'updated',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="m-4">
|
<div class="m-4">
|
||||||
<CollapseContainer title="自定义表单">
|
<CollapseContainer title="自定义表单">
|
||||||
<BasicForm @register="register" @submit="handleSubmit" />
|
<BasicForm @register="register" @submit="handleSubmit">
|
||||||
|
<template #f3="{ model, field }">
|
||||||
|
<a-input v-model:value="model[field]" placeholder="自定义slot" />
|
||||||
|
</template>
|
||||||
|
</BasicForm>
|
||||||
</CollapseContainer>
|
</CollapseContainer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -15,7 +19,7 @@
|
|||||||
{
|
{
|
||||||
field: 'field1',
|
field: 'field1',
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
label: '字段1',
|
label: 'render方式',
|
||||||
colProps: {
|
colProps: {
|
||||||
span: 8,
|
span: 8,
|
||||||
},
|
},
|
||||||
@ -33,7 +37,7 @@
|
|||||||
{
|
{
|
||||||
field: 'field2',
|
field: 'field2',
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
label: '字段2',
|
label: 'render组件slot',
|
||||||
colProps: {
|
colProps: {
|
||||||
span: 8,
|
span: 8,
|
||||||
},
|
},
|
||||||
@ -44,6 +48,16 @@
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: 'field3',
|
||||||
|
component: 'Input',
|
||||||
|
label: '自定义Slot',
|
||||||
|
slot: 'f3',
|
||||||
|
colProps: {
|
||||||
|
span: 8,
|
||||||
|
},
|
||||||
|
rules: [{ required: true }],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { BasicForm, CollapseContainer },
|
components: { BasicForm, CollapseContainer },
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
<CollapseContainer title="动态表单示例,动态根据表单内其他值改变">
|
<CollapseContainer title="动态表单示例,动态根据表单内其他值改变">
|
||||||
<BasicForm @register="register" />
|
<BasicForm @register="register" />
|
||||||
</CollapseContainer>
|
</CollapseContainer>
|
||||||
|
|
||||||
|
<CollapseContainer class="mt-5" title="componentProps动态改变">
|
||||||
|
<BasicForm @register="register1" />
|
||||||
|
</CollapseContainer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@ -120,6 +124,58 @@
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const schemas1: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'f1',
|
||||||
|
component: 'Input',
|
||||||
|
label: 'F1',
|
||||||
|
colProps: {
|
||||||
|
span: 12,
|
||||||
|
},
|
||||||
|
labelWidth: 200,
|
||||||
|
componentProps: ({ formModel }) => {
|
||||||
|
return {
|
||||||
|
placeholder: '同步f2的值为f1',
|
||||||
|
onChange: (e: ChangeEvent) => {
|
||||||
|
formModel.f2 = e.target.value;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'f2',
|
||||||
|
component: 'Input',
|
||||||
|
label: 'F2',
|
||||||
|
colProps: {
|
||||||
|
span: 12,
|
||||||
|
},
|
||||||
|
labelWidth: 200,
|
||||||
|
componentProps: { disabled: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'f3',
|
||||||
|
component: 'Input',
|
||||||
|
label: 'F3',
|
||||||
|
colProps: {
|
||||||
|
span: 12,
|
||||||
|
},
|
||||||
|
labelWidth: 200,
|
||||||
|
// @ts-ignore
|
||||||
|
componentProps: ({ formActionType, tableAction }) => {
|
||||||
|
return {
|
||||||
|
placeholder: '值改变时执行查询,查看控制台',
|
||||||
|
onChange: async () => {
|
||||||
|
const { validate } = formActionType;
|
||||||
|
// tableAction只适用于在表格内开启表单的例子
|
||||||
|
// const { reload } = tableAction;
|
||||||
|
const res = await validate();
|
||||||
|
console.log(res);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { BasicForm, CollapseContainer },
|
components: { BasicForm, CollapseContainer },
|
||||||
setup() {
|
setup() {
|
||||||
@ -133,6 +189,13 @@
|
|||||||
span: 24,
|
span: 24,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const [register1] = useForm({
|
||||||
|
labelWidth: 120,
|
||||||
|
schemas: schemas1,
|
||||||
|
actionColOptions: {
|
||||||
|
span: 24,
|
||||||
|
},
|
||||||
|
});
|
||||||
function changeLabel3() {
|
function changeLabel3() {
|
||||||
updateSchema({
|
updateSchema({
|
||||||
field: 'field3',
|
field: 'field3',
|
||||||
@ -170,6 +233,7 @@
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
register,
|
register,
|
||||||
|
register1,
|
||||||
schemas,
|
schemas,
|
||||||
setProps,
|
setProps,
|
||||||
changeLabel3,
|
changeLabel3,
|
||||||
|
@ -65,7 +65,33 @@
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
rules: [{ required: true, message: '请输入aa' }],
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入aa',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field44',
|
||||||
|
component: 'Input',
|
||||||
|
label: '自定义校验',
|
||||||
|
colProps: {
|
||||||
|
span: 8,
|
||||||
|
},
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
// @ts-ignore
|
||||||
|
validator: async (rule, value) => {
|
||||||
|
if (value === '1') {
|
||||||
|
return Promise.reject('值不能为1');
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'field5',
|
field: 'field5',
|
||||||
|
@ -11,10 +11,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent, ref } from 'vue';
|
||||||
import { BasicForm, FormSchema } from '/@/components/Form/index';
|
import { BasicForm, FormSchema } from '/@/components/Form/index';
|
||||||
import { CollapseContainer } from '/@/components/Container/index';
|
import { CollapseContainer } from '/@/components/Container/index';
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
|
|
||||||
const schemas: FormSchema[] = [
|
const schemas: FormSchema[] = [
|
||||||
{
|
{
|
||||||
field: 'field1',
|
field: 'field1',
|
||||||
@ -23,8 +24,11 @@
|
|||||||
colProps: {
|
colProps: {
|
||||||
span: 8,
|
span: 8,
|
||||||
},
|
},
|
||||||
defaultValue: '111',
|
// componentProps:{},
|
||||||
componentProps: () => {
|
// can func
|
||||||
|
componentProps: ({ schema, formModel }) => {
|
||||||
|
console.log('form:', schema);
|
||||||
|
console.log('formModel:', formModel);
|
||||||
return {
|
return {
|
||||||
placeholder: '自定义placeholder',
|
placeholder: '自定义placeholder',
|
||||||
onChange: (e: any) => {
|
onChange: (e: any) => {
|
||||||
@ -32,14 +36,26 @@
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
renderComponentContent: () => {
|
||||||
|
return {
|
||||||
|
prefix: () => 'pSlot',
|
||||||
|
suffix: () => 'sSlot',
|
||||||
|
};
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'field2',
|
field: 'field2',
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
label: '字段2',
|
label: '字段2',
|
||||||
|
defaultValue: '111',
|
||||||
colProps: {
|
colProps: {
|
||||||
span: 8,
|
span: 8,
|
||||||
},
|
},
|
||||||
|
componentProps: {
|
||||||
|
onChange: (e: any) => {
|
||||||
|
console.log(e);
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'field3',
|
field: 'field3',
|
||||||
@ -111,17 +127,100 @@
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: 'field8',
|
||||||
|
component: 'Checkbox',
|
||||||
|
label: '字段8',
|
||||||
|
colProps: {
|
||||||
|
span: 8,
|
||||||
|
},
|
||||||
|
renderComponentContent: 'Check',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field9',
|
||||||
|
component: 'Switch',
|
||||||
|
label: '字段9',
|
||||||
|
colProps: {
|
||||||
|
span: 8,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field10',
|
||||||
|
component: 'RadioButtonGroup',
|
||||||
|
label: '字段10',
|
||||||
|
colProps: {
|
||||||
|
span: 8,
|
||||||
|
},
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '选项1',
|
||||||
|
value: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '选项2',
|
||||||
|
value: '2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field11',
|
||||||
|
component: 'Cascader',
|
||||||
|
label: '字段11',
|
||||||
|
colProps: {
|
||||||
|
span: 8,
|
||||||
|
},
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: 'zhejiang',
|
||||||
|
label: 'Zhejiang',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
value: 'hangzhou',
|
||||||
|
label: 'Hangzhou',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
value: 'xihu',
|
||||||
|
label: 'West Lake',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'jiangsu',
|
||||||
|
label: 'Jiangsu',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
value: 'nanjing',
|
||||||
|
label: 'Nanjing',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
value: 'zhonghuamen',
|
||||||
|
label: 'Zhong Hua Men',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { BasicForm, CollapseContainer },
|
components: { BasicForm, CollapseContainer },
|
||||||
setup() {
|
setup() {
|
||||||
|
const check = ref(null);
|
||||||
const { createMessage } = useMessage();
|
const { createMessage } = useMessage();
|
||||||
return {
|
return {
|
||||||
schemas,
|
schemas,
|
||||||
handleSubmit: (values: any) => {
|
handleSubmit: (values: any) => {
|
||||||
createMessage.success('click search,values:' + JSON.stringify(values));
|
createMessage.success('click search,values:' + JSON.stringify(values));
|
||||||
},
|
},
|
||||||
|
check,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user