mirror of
https://github.com/imdap/ruoyi-plus-vben5.git
synced 2026-05-05 00:51:26 +08:00
Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into antdv-next
This commit is contained in:
@@ -3,94 +3,60 @@
|
||||
* 可用于 vben-form、vben-modal、vben-drawer 等组件使用,
|
||||
*/
|
||||
|
||||
import type { Component } from 'vue';
|
||||
import type { Component } from "vue";
|
||||
|
||||
import type { BaseFormComponentType } from '@vben/common-ui';
|
||||
import type { Recordable } from '@vben/types';
|
||||
import type { BaseFormComponentType } from "@vben/common-ui";
|
||||
import type { Recordable } from "@vben/types";
|
||||
|
||||
import { computed, defineAsyncComponent, defineComponent, h, ref } from 'vue';
|
||||
import { computed, defineAsyncComponent, defineComponent, h, ref } from "vue";
|
||||
|
||||
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
||||
import { $t } from '@vben/locales';
|
||||
import { ApiComponent, globalShareState, IconPicker } from "@vben/common-ui";
|
||||
import { $t } from "@vben/locales";
|
||||
|
||||
const RichTextarea = defineAsyncComponent(() =>
|
||||
import('#/components/tinymce/index').then((res) => res.Tinymce),
|
||||
import("#/components/tinymce/index").then((res) => res.Tinymce),
|
||||
);
|
||||
|
||||
const FileUpload = defineAsyncComponent(() =>
|
||||
import('#/components/upload').then((res) => res.FileUpload),
|
||||
import("#/components/upload").then((res) => res.FileUpload),
|
||||
);
|
||||
|
||||
const ImageUpload = defineAsyncComponent(() =>
|
||||
import('#/components/upload').then((res) => res.ImageUpload),
|
||||
import("#/components/upload").then((res) => res.ImageUpload),
|
||||
);
|
||||
|
||||
const Button = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/button/index'),
|
||||
);
|
||||
const Cascader = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/cascader/index'),
|
||||
);
|
||||
const Checkbox = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/checkbox/index'),
|
||||
);
|
||||
const CheckboxGroup = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/checkbox/Group'),
|
||||
);
|
||||
const DatePicker = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/date-picker/index'),
|
||||
);
|
||||
const Divider = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/divider/index'),
|
||||
);
|
||||
const Input = defineAsyncComponent(() => import('antdv-next/dist/input/index'));
|
||||
const InputNumber = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/input-number/index'),
|
||||
);
|
||||
const InputPassword = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/input/Password'),
|
||||
);
|
||||
const Mentions = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/mentions/index'),
|
||||
);
|
||||
const Radio = defineAsyncComponent(() => import('antdv-next/dist/radio/index'));
|
||||
const Button = defineAsyncComponent(() => import("antdv-next/dist/button/index"));
|
||||
const Cascader = defineAsyncComponent(() => import("antdv-next/dist/cascader/index"));
|
||||
const Checkbox = defineAsyncComponent(() => import("antdv-next/dist/checkbox/index"));
|
||||
const CheckboxGroup = defineAsyncComponent(() => import("antdv-next/dist/checkbox/Group"));
|
||||
const DatePicker = defineAsyncComponent(() => import("antdv-next/dist/date-picker/index"));
|
||||
const Divider = defineAsyncComponent(() => import("antdv-next/dist/divider/index"));
|
||||
const Input = defineAsyncComponent(() => import("antdv-next/dist/input/index"));
|
||||
const InputNumber = defineAsyncComponent(() => import("antdv-next/dist/input-number/index"));
|
||||
const InputPassword = defineAsyncComponent(() => import("antdv-next/dist/input/Password"));
|
||||
const Mentions = defineAsyncComponent(() => import("antdv-next/dist/mentions/index"));
|
||||
const Radio = defineAsyncComponent(() => import("antdv-next/dist/radio/index"));
|
||||
const RadioGroup = defineAsyncComponent(() =>
|
||||
import('antdv-next/dist/radio/index').then((res) => res.RadioGroup),
|
||||
import("antdv-next/dist/radio/index").then((res) => res.RadioGroup),
|
||||
);
|
||||
const RangePicker = defineAsyncComponent(() =>
|
||||
import('antdv-next/dist/date-picker/index').then(
|
||||
(res) => res.DateRangePicker,
|
||||
),
|
||||
);
|
||||
const Rate = defineAsyncComponent(() => import('antdv-next/dist/rate/index'));
|
||||
const Select = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/select/index'),
|
||||
);
|
||||
const Space = defineAsyncComponent(() => import('antdv-next/dist/space/index'));
|
||||
const Switch = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/switch/index'),
|
||||
);
|
||||
const Textarea = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/input/TextArea'),
|
||||
);
|
||||
const TimePicker = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/time-picker/index'),
|
||||
import("antdv-next/dist/date-picker/index").then((res) => res.DateRangePicker),
|
||||
);
|
||||
const Rate = defineAsyncComponent(() => import("antdv-next/dist/rate/index"));
|
||||
const Select = defineAsyncComponent(() => import("antdv-next/dist/select/index"));
|
||||
const Space = defineAsyncComponent(() => import("antdv-next/dist/space/index"));
|
||||
const Switch = defineAsyncComponent(() => import("antdv-next/dist/switch/index"));
|
||||
const Textarea = defineAsyncComponent(() => import("antdv-next/dist/input/TextArea"));
|
||||
const TimePicker = defineAsyncComponent(() => import("antdv-next/dist/time-picker/index"));
|
||||
const TimeRangePicker = defineAsyncComponent(() =>
|
||||
import('antdv-next/dist/time-picker/index').then(
|
||||
(res) => res.TimeRangePicker,
|
||||
),
|
||||
);
|
||||
const TreeSelect = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/tree-select/index'),
|
||||
);
|
||||
const Upload = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/upload/Upload'),
|
||||
import("antdv-next/dist/time-picker/index").then((res) => res.TimeRangePicker),
|
||||
);
|
||||
const TreeSelect = defineAsyncComponent(() => import("antdv-next/dist/tree-select/index"));
|
||||
const Upload = defineAsyncComponent(() => import("antdv-next/dist/upload/Upload"));
|
||||
|
||||
const withDefaultPlaceholder = <T extends Component>(
|
||||
component: T,
|
||||
type: 'input' | 'select',
|
||||
type: "input" | "select",
|
||||
componentProps: Recordable<any> = {},
|
||||
) => {
|
||||
return defineComponent({
|
||||
@@ -99,10 +65,7 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||
setup: (props: any, { attrs, expose, slots }) => {
|
||||
// 改为placeholder 解决在keepalive & 语言切换 & tab切换 显示不变的问题
|
||||
const computedPlaceholder = computed(
|
||||
() =>
|
||||
props?.placeholder ||
|
||||
attrs?.placeholder ||
|
||||
$t(`ui.placeholder.${type}`),
|
||||
() => props?.placeholder || attrs?.placeholder || $t(`ui.placeholder.${type}`),
|
||||
);
|
||||
|
||||
// 透传组件暴露的方法
|
||||
@@ -134,37 +97,37 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||
|
||||
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
||||
export type ComponentType =
|
||||
| 'ApiCascader'
|
||||
| 'ApiSelect'
|
||||
| 'ApiTreeSelect'
|
||||
| 'AutoComplete'
|
||||
| 'Cascader'
|
||||
| 'Checkbox'
|
||||
| 'CheckboxGroup'
|
||||
| 'DatePicker'
|
||||
| 'DefaultButton'
|
||||
| 'Divider'
|
||||
| 'FileUpload'
|
||||
| 'IconPicker'
|
||||
| 'ImageUpload'
|
||||
| 'Input'
|
||||
| 'InputNumber'
|
||||
| 'InputPassword'
|
||||
| 'Mentions'
|
||||
| 'PrimaryButton'
|
||||
| 'Radio'
|
||||
| 'RadioGroup'
|
||||
| 'RangePicker'
|
||||
| 'Rate'
|
||||
| 'RichTextarea'
|
||||
| 'Select'
|
||||
| 'Space'
|
||||
| 'Switch'
|
||||
| 'Textarea'
|
||||
| 'TimePicker'
|
||||
| 'TimeRangePicker'
|
||||
| 'TreeSelect'
|
||||
| 'Upload'
|
||||
| "ApiCascader"
|
||||
| "ApiSelect"
|
||||
| "ApiTreeSelect"
|
||||
| "AutoComplete"
|
||||
| "Cascader"
|
||||
| "Checkbox"
|
||||
| "CheckboxGroup"
|
||||
| "DatePicker"
|
||||
| "DefaultButton"
|
||||
| "Divider"
|
||||
| "FileUpload"
|
||||
| "IconPicker"
|
||||
| "ImageUpload"
|
||||
| "Input"
|
||||
| "InputNumber"
|
||||
| "InputPassword"
|
||||
| "Mentions"
|
||||
| "PrimaryButton"
|
||||
| "Radio"
|
||||
| "RadioGroup"
|
||||
| "RangePicker"
|
||||
| "Rate"
|
||||
| "RichTextarea"
|
||||
| "Select"
|
||||
| "Space"
|
||||
| "Switch"
|
||||
| "Textarea"
|
||||
| "TimePicker"
|
||||
| "TimeRangePicker"
|
||||
| "TreeSelect"
|
||||
| "Upload"
|
||||
| BaseFormComponentType;
|
||||
|
||||
async function initComponentAdapter() {
|
||||
@@ -173,74 +136,74 @@ async function initComponentAdapter() {
|
||||
// Button: () =>
|
||||
// import('xxx').then((res) => res.Button),
|
||||
|
||||
ApiCascader: withDefaultPlaceholder(ApiComponent, 'select', {
|
||||
ApiCascader: withDefaultPlaceholder(ApiComponent, "select", {
|
||||
component: Cascader,
|
||||
fieldNames: { label: 'label', value: 'value', children: 'children' },
|
||||
loadingSlot: 'suffixIcon',
|
||||
modelPropName: 'value',
|
||||
visibleEvent: 'onVisibleChange',
|
||||
fieldNames: { label: "label", value: "value", children: "children" },
|
||||
loadingSlot: "suffixIcon",
|
||||
modelPropName: "value",
|
||||
visibleEvent: "onVisibleChange",
|
||||
}),
|
||||
ApiSelect: withDefaultPlaceholder(
|
||||
{
|
||||
...ApiComponent,
|
||||
name: 'ApiSelect',
|
||||
name: "ApiSelect",
|
||||
},
|
||||
'select',
|
||||
"select",
|
||||
{
|
||||
component: Select,
|
||||
loadingSlot: 'suffixIcon',
|
||||
visibleEvent: 'onDropdownVisibleChange',
|
||||
modelPropName: 'value',
|
||||
loadingSlot: "suffixIcon",
|
||||
visibleEvent: "onDropdownVisibleChange",
|
||||
modelPropName: "value",
|
||||
},
|
||||
),
|
||||
ApiTreeSelect: withDefaultPlaceholder(
|
||||
{
|
||||
...ApiComponent,
|
||||
name: 'ApiTreeSelect',
|
||||
name: "ApiTreeSelect",
|
||||
},
|
||||
'select',
|
||||
"select",
|
||||
{
|
||||
component: TreeSelect,
|
||||
fieldNames: { label: 'label', value: 'value', children: 'children' },
|
||||
loadingSlot: 'suffixIcon',
|
||||
modelPropName: 'value',
|
||||
optionsPropName: 'treeData',
|
||||
visibleEvent: 'onVisibleChange',
|
||||
fieldNames: { label: "label", value: "value", children: "children" },
|
||||
loadingSlot: "suffixIcon",
|
||||
modelPropName: "value",
|
||||
optionsPropName: "treeData",
|
||||
visibleEvent: "onVisibleChange",
|
||||
},
|
||||
),
|
||||
Cascader: withDefaultPlaceholder(Cascader, 'select'),
|
||||
Cascader: withDefaultPlaceholder(Cascader, "select"),
|
||||
Checkbox,
|
||||
CheckboxGroup,
|
||||
DatePicker,
|
||||
// 自定义默认按钮
|
||||
DefaultButton: (props, { attrs, slots }) => {
|
||||
return h(Button, { ...props, attrs, type: 'default' }, slots);
|
||||
return h(Button, { ...props, attrs, type: "default" }, slots);
|
||||
},
|
||||
Divider,
|
||||
IconPicker: withDefaultPlaceholder(IconPicker, 'select', {
|
||||
iconSlot: 'addonAfter',
|
||||
IconPicker: withDefaultPlaceholder(IconPicker, "select", {
|
||||
iconSlot: "addonAfter",
|
||||
inputComponent: Input,
|
||||
modelValueProp: 'value',
|
||||
modelValueProp: "value",
|
||||
}),
|
||||
Input: withDefaultPlaceholder(Input, 'input'),
|
||||
InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
|
||||
InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
|
||||
Mentions: withDefaultPlaceholder(Mentions, 'input'),
|
||||
Input: withDefaultPlaceholder(Input, "input"),
|
||||
InputNumber: withDefaultPlaceholder(InputNumber, "input"),
|
||||
InputPassword: withDefaultPlaceholder(InputPassword, "input"),
|
||||
Mentions: withDefaultPlaceholder(Mentions, "input"),
|
||||
// 自定义主要按钮
|
||||
PrimaryButton: (props, { attrs, slots }) => {
|
||||
return h(Button, { ...props, attrs, type: 'primary' }, slots);
|
||||
return h(Button, { ...props, attrs, type: "primary" }, slots);
|
||||
},
|
||||
Radio,
|
||||
RadioGroup,
|
||||
RangePicker,
|
||||
Rate,
|
||||
Select: withDefaultPlaceholder(Select, 'select'),
|
||||
Select: withDefaultPlaceholder(Select, "select"),
|
||||
Space,
|
||||
Switch,
|
||||
Textarea: withDefaultPlaceholder(Textarea, 'input'),
|
||||
Textarea: withDefaultPlaceholder(Textarea, "input"),
|
||||
TimePicker,
|
||||
TimeRangePicker,
|
||||
TreeSelect: withDefaultPlaceholder(TreeSelect, 'select'),
|
||||
TreeSelect: withDefaultPlaceholder(TreeSelect, "select"),
|
||||
Upload,
|
||||
ImageUpload,
|
||||
FileUpload,
|
||||
@@ -257,7 +220,7 @@ async function initComponentAdapter() {
|
||||
window.notification.success({
|
||||
description: content,
|
||||
title,
|
||||
placement: 'bottomRight',
|
||||
placement: "bottomRight",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<script lang="ts" setup>
|
||||
import { h, ref } from 'vue';
|
||||
import { h, ref } from "vue";
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
import { Page } from "@vben/common-ui";
|
||||
|
||||
import { useDebounceFn } from '@vueuse/core';
|
||||
import { Button, Card, message, Spin, Tag } from 'antdv-next';
|
||||
import dayjs from 'dayjs';
|
||||
import { useDebounceFn } from "@vueuse/core";
|
||||
import { Button, Card, message, Spin, Tag } from "antdv-next";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
import { useVbenForm, z } from '#/adapter/form';
|
||||
import { getAllMenusApi } from '#/api';
|
||||
import { useVbenForm, z } from "#/adapter/form";
|
||||
import { getAllMenusApi } from "#/api";
|
||||
|
||||
const keyword = ref('');
|
||||
const keyword = ref("");
|
||||
const fetching = ref(false);
|
||||
// 模拟远程获取数据
|
||||
function fetchRemoteOptions({ keyword = '选项' }: Record<string, any>) {
|
||||
function fetchRemoteOptions({ keyword = "选项" }: Record<string, any>) {
|
||||
fetching.value = true;
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
@@ -34,43 +34,43 @@ const [BaseForm, baseFormApi] = useVbenForm({
|
||||
colon: true,
|
||||
// 所有表单项
|
||||
componentProps: {
|
||||
class: 'w-full',
|
||||
class: "w-full",
|
||||
},
|
||||
},
|
||||
fieldMappingTime: [['rangePicker', ['startTime', 'endTime'], 'YYYY-MM-DD']],
|
||||
fieldMappingTime: [["rangePicker", ["startTime", "endTime"], "YYYY-MM-DD"]],
|
||||
// 提交函数
|
||||
handleSubmit: onSubmit,
|
||||
handleValuesChange(_values, fieldsChanged) {
|
||||
message.info(`表单以下字段发生变化:${fieldsChanged.join(',')}`);
|
||||
message.info(`表单以下字段发生变化:${fieldsChanged.join(",")}`);
|
||||
},
|
||||
|
||||
// 垂直布局,label和input在不同行,值为vertical
|
||||
// 水平布局,label和input在同一行
|
||||
layout: 'horizontal',
|
||||
layout: "horizontal",
|
||||
schema: [
|
||||
{
|
||||
// 组件需要在 #/adapter.ts内注册,并加上类型
|
||||
component: 'Input',
|
||||
component: "Input",
|
||||
// 对应组件的参数
|
||||
componentProps: {
|
||||
placeholder: '请输入用户名',
|
||||
placeholder: "请输入用户名",
|
||||
},
|
||||
// 字段名
|
||||
fieldName: 'username',
|
||||
fieldName: "username",
|
||||
// 界面显示的label
|
||||
label: '字符串',
|
||||
rules: 'required',
|
||||
label: "字符串",
|
||||
rules: "required",
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'desc',
|
||||
component: "Input",
|
||||
fieldName: "desc",
|
||||
// 界面显示的description
|
||||
description: '这是表单描述',
|
||||
label: '字符串(带描述)',
|
||||
description: "这是表单描述",
|
||||
label: "字符串(带描述)",
|
||||
},
|
||||
{
|
||||
// 组件需要在 #/adapter.ts内注册,并加上类型
|
||||
component: 'ApiSelect',
|
||||
component: "ApiSelect",
|
||||
// 对应组件的参数
|
||||
componentProps: {
|
||||
// 菜单接口转options格式
|
||||
@@ -82,17 +82,17 @@ const [BaseForm, baseFormApi] = useVbenForm({
|
||||
},
|
||||
// 菜单接口
|
||||
api: getAllMenusApi,
|
||||
autoSelect: 'first',
|
||||
autoSelect: "first",
|
||||
allowClear: true,
|
||||
},
|
||||
// 字段名
|
||||
fieldName: 'api',
|
||||
fieldName: "api",
|
||||
// 界面显示的label
|
||||
label: 'ApiSelect',
|
||||
rules: 'selectRequired',
|
||||
label: "ApiSelect",
|
||||
rules: "selectRequired",
|
||||
},
|
||||
{
|
||||
component: 'ApiSelect',
|
||||
component: "ApiSelect",
|
||||
// 对应组件的参数
|
||||
componentProps: () => {
|
||||
return {
|
||||
@@ -113,244 +113,241 @@ const [BaseForm, baseFormApi] = useVbenForm({
|
||||
};
|
||||
},
|
||||
// 字段名
|
||||
fieldName: 'remoteSearch',
|
||||
fieldName: "remoteSearch",
|
||||
// 界面显示的label
|
||||
label: '远程搜索',
|
||||
label: "远程搜索",
|
||||
renderComponentContent: () => {
|
||||
return {
|
||||
notFoundContent: fetching.value ? h(Spin) : undefined,
|
||||
};
|
||||
},
|
||||
rules: 'selectRequired',
|
||||
rules: "selectRequired",
|
||||
},
|
||||
{
|
||||
component: 'ApiTreeSelect',
|
||||
component: "ApiTreeSelect",
|
||||
// 对应组件的参数
|
||||
componentProps: {
|
||||
// 菜单接口
|
||||
api: getAllMenusApi,
|
||||
// 菜单接口转options格式
|
||||
labelField: 'name',
|
||||
valueField: 'path',
|
||||
childrenField: 'children',
|
||||
labelField: "name",
|
||||
valueField: "path",
|
||||
childrenField: "children",
|
||||
},
|
||||
// 字段名
|
||||
fieldName: 'apiTree',
|
||||
fieldName: "apiTree",
|
||||
// 界面显示的label
|
||||
label: 'ApiTreeSelect',
|
||||
label: "ApiTreeSelect",
|
||||
},
|
||||
{
|
||||
component: 'InputPassword',
|
||||
component: "InputPassword",
|
||||
componentProps: {
|
||||
placeholder: '请输入密码',
|
||||
placeholder: "请输入密码",
|
||||
},
|
||||
fieldName: 'password',
|
||||
label: '密码',
|
||||
fieldName: "password",
|
||||
label: "密码",
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
component: "InputNumber",
|
||||
componentProps: {
|
||||
placeholder: '请输入',
|
||||
placeholder: "请输入",
|
||||
},
|
||||
fieldName: 'number',
|
||||
label: '数字(带后缀)',
|
||||
fieldName: "number",
|
||||
label: "数字(带后缀)",
|
||||
},
|
||||
{
|
||||
component: 'IconPicker',
|
||||
fieldName: 'icon',
|
||||
label: '图标',
|
||||
component: "IconPicker",
|
||||
fieldName: "icon",
|
||||
label: "图标",
|
||||
},
|
||||
{
|
||||
colon: false,
|
||||
component: 'Select',
|
||||
component: "Select",
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
filterOption: true,
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
label: "选项1",
|
||||
value: "1",
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
label: "选项2",
|
||||
value: "2",
|
||||
},
|
||||
],
|
||||
placeholder: '请选择',
|
||||
placeholder: "请选择",
|
||||
showSearch: true,
|
||||
},
|
||||
fieldName: 'options',
|
||||
label: () => h(Tag, { color: 'warning' }, () => '😎自定义:'),
|
||||
fieldName: "options",
|
||||
label: () => h(Tag, { color: "warning" }, () => "😎自定义:"),
|
||||
},
|
||||
{
|
||||
component: 'RadioGroup',
|
||||
component: "RadioGroup",
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
label: "选项1",
|
||||
value: "1",
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
label: "选项2",
|
||||
value: "2",
|
||||
},
|
||||
],
|
||||
},
|
||||
fieldName: 'radioGroup',
|
||||
label: '单选组',
|
||||
fieldName: "radioGroup",
|
||||
label: "单选组",
|
||||
},
|
||||
{
|
||||
component: 'Radio',
|
||||
fieldName: 'radio',
|
||||
label: '',
|
||||
component: "Radio",
|
||||
fieldName: "radio",
|
||||
label: "",
|
||||
renderComponentContent: () => {
|
||||
return {
|
||||
default: () => ['Radio'],
|
||||
default: () => ["Radio"],
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'CheckboxGroup',
|
||||
component: "CheckboxGroup",
|
||||
componentProps: {
|
||||
name: 'cname',
|
||||
name: "cname",
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
label: "选项1",
|
||||
value: "1",
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
label: "选项2",
|
||||
value: "2",
|
||||
},
|
||||
],
|
||||
},
|
||||
fieldName: 'checkboxGroup',
|
||||
label: '多选组',
|
||||
fieldName: "checkboxGroup",
|
||||
label: "多选组",
|
||||
},
|
||||
{
|
||||
component: 'Checkbox',
|
||||
fieldName: 'checkbox',
|
||||
label: '',
|
||||
component: "Checkbox",
|
||||
fieldName: "checkbox",
|
||||
label: "",
|
||||
renderComponentContent: () => {
|
||||
return {
|
||||
default: () => ['我已阅读并同意'],
|
||||
default: () => ["我已阅读并同意"],
|
||||
};
|
||||
},
|
||||
rules: z
|
||||
.boolean()
|
||||
.refine((v) => v, { message: '为什么不同意?勾上它!' }),
|
||||
rules: z.boolean().refine((v) => v, { message: "为什么不同意?勾上它!" }),
|
||||
},
|
||||
{
|
||||
component: 'Mentions',
|
||||
component: "Mentions",
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: 'afc163',
|
||||
value: 'afc163',
|
||||
label: "afc163",
|
||||
value: "afc163",
|
||||
},
|
||||
{
|
||||
label: 'zombieJ',
|
||||
value: 'zombieJ',
|
||||
label: "zombieJ",
|
||||
value: "zombieJ",
|
||||
},
|
||||
],
|
||||
placeholder: '请输入',
|
||||
placeholder: "请输入",
|
||||
},
|
||||
fieldName: 'mentions',
|
||||
label: '提及',
|
||||
fieldName: "mentions",
|
||||
label: "提及",
|
||||
},
|
||||
{
|
||||
component: 'Rate',
|
||||
fieldName: 'rate',
|
||||
label: '评分',
|
||||
component: "Rate",
|
||||
fieldName: "rate",
|
||||
label: "评分",
|
||||
},
|
||||
{
|
||||
component: 'Switch',
|
||||
component: "Switch",
|
||||
componentProps: {
|
||||
class: 'w-auto',
|
||||
class: "w-auto",
|
||||
},
|
||||
fieldName: 'switch',
|
||||
help: () =>
|
||||
['这是一个多行帮助信息', '第二行', '第三行'].map((v) => h('p', v)),
|
||||
label: '开关',
|
||||
fieldName: "switch",
|
||||
help: () => ["这是一个多行帮助信息", "第二行", "第三行"].map((v) => h("p", v)),
|
||||
label: "开关",
|
||||
},
|
||||
{
|
||||
component: 'DatePicker',
|
||||
fieldName: 'datePicker',
|
||||
label: '日期选择框',
|
||||
rules: 'selectRequired',
|
||||
component: "DatePicker",
|
||||
fieldName: "datePicker",
|
||||
label: "日期选择框",
|
||||
rules: "selectRequired",
|
||||
},
|
||||
{
|
||||
component: 'RangePicker',
|
||||
fieldName: 'rangePicker',
|
||||
label: '范围选择器',
|
||||
rules: 'selectRequired',
|
||||
component: "RangePicker",
|
||||
fieldName: "rangePicker",
|
||||
label: "范围选择器",
|
||||
rules: "selectRequired",
|
||||
},
|
||||
{
|
||||
component: 'TimeRangePicker',
|
||||
fieldName: 'timeRangePicker',
|
||||
label: '时间范围选择器',
|
||||
rules: 'selectRequired',
|
||||
component: "TimeRangePicker",
|
||||
fieldName: "timeRangePicker",
|
||||
label: "时间范围选择器",
|
||||
rules: "selectRequired",
|
||||
},
|
||||
{
|
||||
component: 'TimePicker',
|
||||
fieldName: 'timePicker',
|
||||
label: '时间选择框',
|
||||
rules: 'selectRequired',
|
||||
component: "TimePicker",
|
||||
fieldName: "timePicker",
|
||||
label: "时间选择框",
|
||||
rules: "selectRequired",
|
||||
},
|
||||
{
|
||||
rules: 'selectRequired',
|
||||
component: 'TreeSelect',
|
||||
rules: "selectRequired",
|
||||
component: "TreeSelect",
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
placeholder: '请选择',
|
||||
placeholder: "请选择",
|
||||
showSearch: true,
|
||||
treeData: [
|
||||
{
|
||||
label: 'root 1',
|
||||
value: 'root 1',
|
||||
label: "root 1",
|
||||
value: "root 1",
|
||||
children: [
|
||||
{
|
||||
label: 'parent 1',
|
||||
value: 'parent 1',
|
||||
label: "parent 1",
|
||||
value: "parent 1",
|
||||
children: [
|
||||
{
|
||||
label: 'parent 1-0',
|
||||
value: 'parent 1-0',
|
||||
label: "parent 1-0",
|
||||
value: "parent 1-0",
|
||||
children: [
|
||||
{
|
||||
label: 'my leaf',
|
||||
value: 'leaf1',
|
||||
label: "my leaf",
|
||||
value: "leaf1",
|
||||
},
|
||||
{
|
||||
label: 'your leaf',
|
||||
value: 'leaf2',
|
||||
label: "your leaf",
|
||||
value: "leaf2",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'parent 1-1',
|
||||
value: 'parent 1-1',
|
||||
label: "parent 1-1",
|
||||
value: "parent 1-1",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'parent 2',
|
||||
value: 'parent 2',
|
||||
label: "parent 2",
|
||||
value: "parent 2",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
treeNodeFilterProp: 'label',
|
||||
treeNodeFilterProp: "label",
|
||||
},
|
||||
fieldName: 'treeSelect',
|
||||
label: '树选择',
|
||||
fieldName: "treeSelect",
|
||||
label: "树选择",
|
||||
},
|
||||
].map((i) => ({
|
||||
...i,
|
||||
rules: 'required',
|
||||
rules: "required",
|
||||
})),
|
||||
// 大屏一行显示3个,中屏一行显示2个,小屏一行显示1个
|
||||
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
|
||||
wrapperClass: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
|
||||
});
|
||||
|
||||
function onSubmit() {}
|
||||
@@ -360,31 +357,31 @@ function handleSetFormValue() {
|
||||
* 设置表单值(多个)
|
||||
*/
|
||||
baseFormApi.setValues({
|
||||
checkboxGroup: ['1'],
|
||||
datePicker: dayjs('2022-01-01'),
|
||||
checkboxGroup: ["1"],
|
||||
datePicker: dayjs("2022-01-01"),
|
||||
files: [
|
||||
{
|
||||
name: 'example.png',
|
||||
status: 'done',
|
||||
uid: '-1',
|
||||
url: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
|
||||
name: "example.png",
|
||||
status: "done",
|
||||
uid: "-1",
|
||||
url: "https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp",
|
||||
},
|
||||
],
|
||||
mentions: '@afc163',
|
||||
mentions: "@afc163",
|
||||
number: 3,
|
||||
options: '1',
|
||||
password: '2',
|
||||
radioGroup: '1',
|
||||
rangePicker: [dayjs('2022-01-01'), dayjs('2022-01-02')],
|
||||
options: "1",
|
||||
password: "2",
|
||||
radioGroup: "1",
|
||||
rangePicker: [dayjs("2022-01-01"), dayjs("2022-01-02")],
|
||||
rate: 3,
|
||||
switch: true,
|
||||
timePicker: dayjs('2022-01-01 12:00:00'),
|
||||
treeSelect: 'leaf1',
|
||||
username: '1',
|
||||
timePicker: dayjs("2022-01-01 12:00:00"),
|
||||
treeSelect: "leaf1",
|
||||
username: "1",
|
||||
});
|
||||
|
||||
// 设置单个表单值
|
||||
baseFormApi.setFieldValue('checkbox', true);
|
||||
baseFormApi.setFieldValue("checkbox", true);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user