docs: update docs (#4466)

* chore: fixed known issues with form components

* docs: add vben form doc
This commit is contained in:
Vben
2024-09-22 14:16:06 +08:00
committed by GitHub
parent dac80703d9
commit 5ce3a18785
36 changed files with 1938 additions and 139 deletions

View File

@@ -0,0 +1,6 @@
<script lang="ts" setup>
import { VbenCountToAnimator } from '@vben/common-ui';
</script>
<template>
<VbenCountToAnimator :duration="3000" :end-val="30000" :start-val="1" />
</template>

View File

@@ -0,0 +1,12 @@
<script lang="ts" setup>
import { VbenCountToAnimator } from '@vben/common-ui';
</script>
<template>
<VbenCountToAnimator
:duration="3000"
:end-val="2000000"
:start-val="1"
prefix="$"
separator="/"
/>
</template>

View File

@@ -0,0 +1,236 @@
<script lang="ts" setup>
import { Button, message, Space } from 'ant-design-vue';
import { useVbenForm } from '#/adapter';
const [BaseForm, formApi] = useVbenForm({
// 所有表单项共用,可单独在表单内覆盖
commonConfig: {
// 所有表单项
componentProps: {
class: 'w-full',
},
},
// 使用 tailwindcss grid布局
// 提交函数
handleSubmit: onSubmit,
// 垂直布局label和input在不同行值为vertical
layout: 'horizontal',
// 水平布局label和input在同一行
schema: [
{
// 组件需要在 #/adapter.ts内注册并加上类型
component: 'Input',
// 对应组件的参数
componentProps: {
placeholder: '请输入用户名',
},
// 字段名
fieldName: 'field1',
// 界面显示的label
label: 'field1',
},
{
component: 'Select',
componentProps: {
allowClear: true,
filterOption: true,
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
placeholder: '请选择',
showSearch: true,
},
fieldName: 'fieldOptions',
label: '下拉选',
},
],
wrapperClass: 'grid-cols-1 md:grid-cols-2',
});
function onSubmit(values: Record<string, any>) {
message.success({
content: `form values: ${JSON.stringify(values)}`,
});
}
function handleClick(
action:
| 'batchAddSchema'
| 'batchDeleteSchema'
| 'disabled'
| 'hiddenAction'
| 'hiddenResetButton'
| 'hiddenSubmitButton'
| 'labelWidth'
| 'resetDisabled'
| 'resetLabelWidth'
| 'showAction'
| 'showResetButton'
| 'showSubmitButton'
| 'updateActionAlign'
| 'updateResetButton'
| 'updateSchema'
| 'updateSubmitButton',
) {
switch (action) {
case 'updateSchema': {
formApi.updateSchema([
{
componentProps: {
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
{
label: '选项3',
value: '3',
},
],
},
fieldName: 'fieldOptions',
},
]);
message.success('字段 `fieldOptions` 下拉选项更新成功。');
break;
}
case 'labelWidth': {
formApi.setState({
commonConfig: {
labelWidth: 150,
},
});
break;
}
case 'resetLabelWidth': {
formApi.setState({
commonConfig: {
labelWidth: 100,
},
});
break;
}
case 'disabled': {
formApi.setState({ commonConfig: { disabled: true } });
break;
}
case 'resetDisabled': {
formApi.setState({ commonConfig: { disabled: false } });
break;
}
case 'hiddenAction': {
formApi.setState({ showDefaultActions: false });
break;
}
case 'showAction': {
formApi.setState({ showDefaultActions: true });
break;
}
case 'hiddenResetButton': {
formApi.setState({ resetButtonOptions: { show: false } });
break;
}
case 'showResetButton': {
formApi.setState({ resetButtonOptions: { show: true } });
break;
}
case 'hiddenSubmitButton': {
formApi.setState({ submitButtonOptions: { show: false } });
break;
}
case 'showSubmitButton': {
formApi.setState({ submitButtonOptions: { show: true } });
break;
}
case 'updateResetButton': {
formApi.setState({
resetButtonOptions: { disabled: true },
});
break;
}
case 'updateSubmitButton': {
formApi.setState({
submitButtonOptions: { loading: true },
});
break;
}
case 'updateActionAlign': {
formApi.setState({
// 可以自行调整class
actionWrapperClass: 'text-center',
});
break;
}
case 'batchAddSchema': {
formApi.setState((prev) => {
const currentSchema = prev?.schema ?? [];
const newSchema = [];
for (let i = 0; i < 2; i++) {
newSchema.push({
component: 'Input',
componentProps: {
placeholder: '请输入',
},
fieldName: `field${i}${Date.now()}`,
label: `field+`,
});
}
return {
schema: [...currentSchema, ...newSchema],
};
});
break;
}
case 'batchDeleteSchema': {
formApi.setState((prev) => {
const currentSchema = prev?.schema ?? [];
return {
schema: currentSchema.slice(0, -2),
};
});
break;
}
}
}
</script>
<template>
<div>
<Space class="mb-5 flex-wrap">
<Button @click="handleClick('updateSchema')">updateSchema</Button>
<Button @click="handleClick('labelWidth')">更改labelWidth</Button>
<Button @click="handleClick('resetLabelWidth')">还原labelWidth</Button>
<Button @click="handleClick('disabled')">禁用表单</Button>
<Button @click="handleClick('resetDisabled')">解除禁用</Button>
<Button @click="handleClick('hiddenAction')">隐藏操作按钮</Button>
<Button @click="handleClick('showAction')">显示操作按钮</Button>
<Button @click="handleClick('hiddenResetButton')">隐藏重置按钮</Button>
<Button @click="handleClick('showResetButton')">显示重置按钮</Button>
<Button @click="handleClick('hiddenSubmitButton')">隐藏提交按钮</Button>
<Button @click="handleClick('showSubmitButton')">显示提交按钮</Button>
<Button @click="handleClick('updateResetButton')">修改重置按钮</Button>
<Button @click="handleClick('updateSubmitButton')">修改提交按钮</Button>
<Button @click="handleClick('updateActionAlign')">
调整操作按钮位置
</Button>
<Button @click="handleClick('batchAddSchema')"> 批量添加表单项 </Button>
<Button @click="handleClick('batchDeleteSchema')">
批量删除表单项
</Button>
</Space>
<BaseForm />
</div>
</template>

View File

@@ -0,0 +1,231 @@
<script lang="ts" setup>
import { message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter';
const [BaseForm] = useVbenForm({
// 所有表单项共用,可单独在表单内覆盖
commonConfig: {
// 所有表单项
componentProps: {
class: 'w-full',
},
},
// 提交函数
handleSubmit: onSubmit,
// 垂直布局label和input在不同行值为vertical
// 水平布局label和input在同一行
layout: 'horizontal',
schema: [
{
// 组件需要在 #/adapter.ts内注册并加上类型
component: 'Input',
// 对应组件的参数
componentProps: {
placeholder: '请输入用户名',
},
// 字段名
fieldName: 'username',
// 界面显示的label
label: '字符串',
},
{
component: 'InputPassword',
componentProps: {
placeholder: '请输入密码',
},
fieldName: 'password',
label: '密码',
},
{
component: 'InputNumber',
componentProps: {
placeholder: '请输入',
},
fieldName: 'number',
label: '数字(带后缀)',
suffix: () => '¥',
},
{
component: 'Select',
componentProps: {
allowClear: true,
filterOption: true,
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
placeholder: '请选择',
showSearch: true,
},
fieldName: 'options',
label: '下拉选',
},
{
component: 'RadioGroup',
componentProps: {
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
},
fieldName: 'radioGroup',
label: '单选组',
},
{
component: 'Radio',
fieldName: 'radio',
label: '',
renderComponentContent: () => {
return {
default: () => ['Radio'],
};
},
},
{
component: 'CheckboxGroup',
componentProps: {
name: 'cname',
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
},
fieldName: 'checkboxGroup',
label: '多选组',
},
{
component: 'Checkbox',
fieldName: 'checkbox',
label: '',
renderComponentContent: () => {
return {
default: () => ['我已阅读并同意'],
};
},
},
{
component: 'Mentions',
componentProps: {
options: [
{
label: 'afc163',
value: 'afc163',
},
{
label: 'zombieJ',
value: 'zombieJ',
},
],
placeholder: '请输入',
},
fieldName: 'mentions',
label: '提及',
},
{
component: 'Rate',
fieldName: 'rate',
label: '评分',
},
{
component: 'Switch',
componentProps: {
class: 'w-auto',
},
fieldName: 'switch',
label: '开关',
},
{
component: 'DatePicker',
fieldName: 'datePicker',
label: '日期选择框',
},
{
component: 'RangePicker',
fieldName: 'rangePicker',
label: '范围选择器',
},
{
component: 'TimePicker',
fieldName: 'timePicker',
label: '时间选择框',
},
{
component: 'TreeSelect',
componentProps: {
allowClear: true,
placeholder: '请选择',
showSearch: true,
treeData: [
{
label: 'root 1',
value: 'root 1',
children: [
{
label: 'parent 1',
value: 'parent 1',
children: [
{
label: 'parent 1-0',
value: 'parent 1-0',
children: [
{
label: 'my leaf',
value: 'leaf1',
},
{
label: 'your leaf',
value: 'leaf2',
},
],
},
{
label: 'parent 1-1',
value: 'parent 1-1',
},
],
},
{
label: 'parent 2',
value: 'parent 2',
},
],
},
],
treeNodeFilterProp: 'label',
},
fieldName: 'treeSelect',
label: '树选择',
},
],
wrapperClass: 'grid-cols-1',
});
function onSubmit(values: Record<string, any>) {
message.success({
content: `form values: ${JSON.stringify(values)}`,
});
}
</script>
<template>
<BaseForm />
</template>

View File

@@ -0,0 +1,68 @@
<script lang="ts" setup>
import { h } from 'vue';
import { Input, message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter';
const [Form] = useVbenForm({
// 所有表单项共用,可单独在表单内覆盖
commonConfig: {
// 所有表单项
componentProps: {
class: 'w-full',
},
labelClass: 'w-2/6',
},
// 提交函数
handleSubmit: onSubmit,
// 垂直布局label和input在不同行值为vertical
// 水平布局label和input在同一行
layout: 'horizontal',
schema: [
{
// 组件需要在 #/adapter.ts内注册并加上类型
component: 'Input',
fieldName: 'field',
label: '自定义后缀',
suffix: () => h('span', { class: 'text-red-600' }, '元'),
},
{
component: 'Input',
fieldName: 'field1',
label: '自定义组件slot',
renderComponentContent: () => ({
prefix: () => 'prefix',
suffix: () => 'suffix',
}),
},
{
component: h(Input, { placeholder: '请输入' }),
fieldName: 'field2',
label: '自定义组件',
rules: 'required',
},
{
component: 'Input',
fieldName: 'field3',
label: '自定义组件(slot)',
rules: 'required',
},
],
wrapperClass: 'grid-cols-1',
});
function onSubmit(values: Record<string, any>) {
message.success({
content: `form values: ${JSON.stringify(values)}`,
});
}
</script>
<template>
<Form>
<template #field3="slotProps">
<Input placeholder="请输入" v-bind="slotProps" />
</template>
</Form>
</template>

View File

@@ -0,0 +1,168 @@
<script lang="ts" setup>
import { message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter';
const [Form] = useVbenForm({
// 提交函数
handleSubmit: onSubmit,
schema: [
{
component: 'Input',
defaultValue: 'hidden value',
dependencies: {
show: false,
// 随意一个字段改变时,都会触发
triggerFields: ['field1Switch'],
},
fieldName: 'hiddenField',
label: '隐藏字段',
},
{
component: 'Switch',
defaultValue: true,
fieldName: 'field1Switch',
help: '通过Dom控制销毁',
label: '显示字段1',
},
{
component: 'Switch',
defaultValue: true,
fieldName: 'field2Switch',
help: '通过css控制隐藏',
label: '显示字段2',
},
{
component: 'Switch',
fieldName: 'field3Switch',
label: '禁用字段3',
},
{
component: 'Switch',
fieldName: 'field4Switch',
label: '字段4必填',
},
{
component: 'Input',
dependencies: {
if(values) {
return !!values.field1Switch;
},
// 只有指定的字段改变时,才会触发
triggerFields: ['field1Switch'],
},
// 字段名
fieldName: 'field1',
// 界面显示的label
label: '字段1',
},
{
component: 'Input',
dependencies: {
show(values) {
return !!values.field2Switch;
},
triggerFields: ['field2Switch'],
},
fieldName: 'field2',
label: '字段2',
},
{
component: 'Input',
dependencies: {
disabled(values) {
return !!values.field3Switch;
},
triggerFields: ['field3Switch'],
},
fieldName: 'field3',
label: '字段3',
},
{
component: 'Input',
dependencies: {
required(values) {
return !!values.field4Switch;
},
triggerFields: ['field4Switch'],
},
fieldName: 'field4',
label: '字段4',
},
{
component: 'Input',
dependencies: {
rules(values) {
if (values.field1 === '123') {
return 'required';
}
return null;
},
triggerFields: ['field1'],
},
fieldName: 'field5',
help: '当字段1的值为`123`时,必填',
label: '动态rules',
},
{
component: 'Select',
componentProps: {
allowClear: true,
class: 'w-full',
filterOption: true,
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
placeholder: '请选择',
showSearch: true,
},
dependencies: {
componentProps(values) {
if (values.field2 === '123') {
return {
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
{
label: '选项3',
value: '3',
},
],
};
}
return {};
},
triggerFields: ['field2'],
},
fieldName: 'field6',
help: '当字段2的值为`123`时,更改下拉选项',
label: '动态配置',
},
],
// 大屏一行显示3个中屏一行显示2个小屏一行显示1个
wrapperClass: 'grid-cols-1 md:grid-cols-2',
});
function onSubmit(values: Record<string, any>) {
message.success({
content: `form values: ${JSON.stringify(values)}`,
});
}
</script>
<template>
<Form />
</template>

View File

@@ -0,0 +1,94 @@
<script lang="ts" setup>
import { message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter';
const [QueryForm] = useVbenForm({
// 默认展开
collapsed: false,
// 所有表单项共用,可单独在表单内覆盖
commonConfig: {
// 所有表单项
componentProps: {
class: 'w-full',
},
},
// 提交函数
handleSubmit: onSubmit,
// 垂直布局label和input在不同行值为vertical
// 水平布局label和input在同一行
layout: 'horizontal',
schema: [
{
// 组件需要在 #/adapter.ts内注册并加上类型
component: 'Input',
// 对应组件的参数
componentProps: {
placeholder: '请输入用户名',
},
// 字段名
fieldName: 'username',
// 界面显示的label
label: '字符串',
},
{
component: 'InputPassword',
componentProps: {
placeholder: '请输入密码',
},
fieldName: 'password',
label: '密码',
},
{
component: 'InputNumber',
componentProps: {
placeholder: '请输入',
},
fieldName: 'number',
label: '数字(带后缀)',
suffix: () => '¥',
},
{
component: 'Select',
componentProps: {
allowClear: true,
filterOption: true,
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
placeholder: '请选择',
showSearch: true,
},
fieldName: 'options',
label: '下拉选',
},
{
component: 'DatePicker',
fieldName: 'datePicker',
label: '日期选择框',
},
],
// 是否可展开
showCollapseButton: true,
submitButtonOptions: {
text: '查询',
},
wrapperClass: 'grid-cols-1 md:grid-cols-2',
});
function onSubmit(values: Record<string, any>) {
message.success({
content: `form values: ${JSON.stringify(values)}`,
});
}
</script>
<template>
<QueryForm />
</template>

View File

@@ -0,0 +1,189 @@
<script lang="ts" setup>
import { message } from 'ant-design-vue';
import { useVbenForm, z } from '#/adapter';
const [Form] = useVbenForm({
// 所有表单项共用,可单独在表单内覆盖
commonConfig: {
// 所有表单项
componentProps: {
class: 'w-full',
},
},
// 提交函数
handleSubmit: onSubmit,
// 垂直布局label和input在不同行值为vertical
// 水平布局label和input在同一行
layout: 'horizontal',
schema: [
{
// 组件需要在 #/adapter.ts内注册并加上类型
component: 'Input',
// 对应组件的参数
componentProps: {
placeholder: '请输入',
},
// 字段名
fieldName: 'field1',
// 界面显示的label
label: '字段1',
rules: 'required',
},
{
component: 'Input',
componentProps: {
placeholder: '请输入',
},
defaultValue: '默认值',
fieldName: 'field2',
label: '默认值(必填)',
rules: 'required',
},
{
component: 'Input',
componentProps: {
placeholder: '请输入',
},
fieldName: 'field3',
label: '默认值(非必填)',
rules: z.string().default('默认值').optional(),
},
{
component: 'Input',
componentProps: {
placeholder: '请输入',
},
fieldName: 'field31',
label: '自定义信息',
rules: z.string().min(1, { message: '最少输入1个字符' }),
},
{
component: 'Input',
// 对应组件的参数
componentProps: {
placeholder: '请输入',
},
// 字段名
fieldName: 'field4',
// 界面显示的label
label: '邮箱',
rules: z.string().email('请输入正确的邮箱'),
},
{
component: 'InputNumber',
componentProps: {
placeholder: '请输入',
},
fieldName: 'number',
label: '数字',
rules: 'required',
},
{
component: 'Select',
componentProps: {
allowClear: true,
filterOption: true,
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
placeholder: '请选择',
showSearch: true,
},
defaultValue: undefined,
fieldName: 'options',
label: '下拉选',
rules: 'selectRequired',
},
{
component: 'RadioGroup',
componentProps: {
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
},
fieldName: 'radioGroup',
label: '单选组',
rules: 'selectRequired',
},
{
component: 'CheckboxGroup',
componentProps: {
name: 'cname',
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
},
fieldName: 'checkboxGroup',
label: '多选组',
rules: 'selectRequired',
},
{
component: 'Checkbox',
fieldName: 'checkbox',
label: '',
renderComponentContent: () => {
return {
default: () => ['我已阅读并同意'],
};
},
rules: 'selectRequired',
},
{
component: 'DatePicker',
defaultValue: undefined,
fieldName: 'datePicker',
label: '日期选择框',
rules: 'selectRequired',
},
{
component: 'RangePicker',
defaultValue: undefined,
fieldName: 'rangePicker',
label: '区间选择框',
rules: 'selectRequired',
},
{
component: 'InputPassword',
componentProps: {
placeholder: '请输入',
},
fieldName: 'password',
label: '密码',
rules: 'required',
},
],
wrapperClass: 'grid-cols-1',
});
function onSubmit(values: Record<string, any>) {
message.success({
content: `form values: ${JSON.stringify(values)}`,
});
}
</script>
<template>
<Form />
</template>