Netfan преди 1 месец
родител
ревизия
eba372062e

+ 1 - 0
playground/src/locales/langs/en-US/examples.json

@@ -12,6 +12,7 @@
   "form": {
     "title": "Form",
     "basic": "Basic Form",
+    "layout": "Custom Layout",
     "query": "Query Form",
     "rules": "Form Rules",
     "dynamic": "Dynamic Form",

+ 1 - 0
playground/src/locales/langs/zh-CN/examples.json

@@ -15,6 +15,7 @@
   "form": {
     "title": "表单",
     "basic": "基础表单",
+    "layout": "自定义布局",
     "query": "查询表单",
     "rules": "表单校验",
     "dynamic": "动态表单",

+ 8 - 0
playground/src/router/routes/modules/examples.ts

@@ -53,6 +53,14 @@ const routes: RouteRecordRaw[] = [
               title: $t('examples.form.dynamic'),
             },
           },
+          {
+            name: 'FormLayoutExample',
+            path: '/examples/form/custom-layout',
+            component: () => import('#/views/examples/form/custom-layout.vue'),
+            meta: {
+              title: $t('examples.form.layout'),
+            },
+          },
           {
             name: 'FormCustomExample',
             path: '/examples/form/custom',

+ 2 - 88
playground/src/views/examples/form/basic.vue

@@ -4,15 +4,7 @@ import { h, ref } from 'vue';
 import { Page } from '@vben/common-ui';
 
 import { useDebounceFn } from '@vueuse/core';
-import {
-  Button,
-  Card,
-  message,
-  Spin,
-  TabPane,
-  Tabs,
-  Tag,
-} from 'ant-design-vue';
+import { Button, Card, message, Spin, Tag } from 'ant-design-vue';
 import dayjs from 'dayjs';
 
 import { useVbenForm, z } from '#/adapter/form';
@@ -20,7 +12,6 @@ import { getAllMenusApi } from '#/api';
 
 import DocButton from '../doc-button.vue';
 
-const activeTab = ref('basic');
 const keyword = ref('');
 const fetching = ref(false);
 // 模拟远程获取数据
@@ -339,75 +330,6 @@ const [BaseForm, baseFormApi] = useVbenForm({
   wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
 });
 
-const [CustomLayoutForm] = useVbenForm({
-  // 所有表单项共用,可单独在表单内覆盖
-  commonConfig: {
-    // 所有表单项
-    componentProps: {
-      class: 'w-full',
-    },
-  },
-  layout: 'horizontal',
-  schema: [
-    {
-      component: 'Select',
-      fieldName: 'field1',
-      label: '字符串',
-    },
-    {
-      component: 'TreeSelect',
-      fieldName: 'field2',
-      label: '字符串',
-    },
-    {
-      component: 'Mentions',
-      fieldName: 'field3',
-      label: '字符串',
-    },
-    {
-      component: 'Input',
-      fieldName: 'field4',
-      label: '字符串',
-    },
-    {
-      component: 'InputNumber',
-      fieldName: 'field5',
-      // 从第三列开始 相当于中间空了一列
-      formItemClass: 'col-start-3',
-      label: '前面空了一列',
-    },
-    {
-      component: 'Textarea',
-      fieldName: 'field6',
-      // 占满三列空间 基线对齐
-      formItemClass: 'col-span-3 items-baseline',
-      label: '占满三列',
-    },
-    {
-      component: 'Input',
-      fieldName: 'field7',
-      // 占满2列空间 从第二列开始 相当于前面空了一列
-      formItemClass: 'col-span-2 col-start-2',
-      label: '占满2列',
-    },
-    {
-      component: 'Input',
-      fieldName: 'field8',
-      // 左右留空
-      formItemClass: 'col-start-2',
-      label: '左右留空',
-    },
-    {
-      component: 'InputPassword',
-      fieldName: 'field9',
-      formItemClass: 'col-start-1',
-      label: '字符串',
-    },
-  ],
-  // 一共三列
-  wrapperClass: 'grid-cols-3',
-});
-
 function onSubmit(values: Record<string, any>) {
   message.success({
     content: `form values: ${JSON.stringify(values)}`,
@@ -443,7 +365,6 @@ function handleSetFormValue() {
   <Page
     content-class="flex flex-col gap-4"
     description="表单组件基础示例,请注意,该页面用到的参数代码会添加一些简单注释,方便理解,请仔细查看。"
-    header-class="pb-0"
     title="表单组件"
   >
     <template #description>
@@ -452,22 +373,15 @@ function handleSetFormValue() {
           表单组件基础示例,请注意,该页面用到的参数代码会添加一些简单注释,方便理解,请仔细查看。
         </p>
       </div>
-      <Tabs v-model:active-key="activeTab" :tab-bar-style="{ marginBottom: 0 }">
-        <TabPane key="basic" tab="基础示例" />
-        <TabPane key="layout" tab="自定义布局" />
-      </Tabs>
     </template>
     <template #extra>
       <DocButton class="mb-2" path="/components/common-ui/vben-form" />
     </template>
-    <Card v-show="activeTab === 'basic'" title="基础示例">
+    <Card title="基础示例">
       <template #extra>
         <Button type="primary" @click="handleSetFormValue">设置表单值</Button>
       </template>
       <BaseForm />
     </Card>
-    <Card v-show="activeTab === 'layout'" title="使用tailwind自定义布局">
-      <CustomLayoutForm />
-    </Card>
   </Page>
 </template>

+ 111 - 0
playground/src/views/examples/form/custom-layout.vue

@@ -0,0 +1,111 @@
+<script lang="ts" setup>
+import { h } from 'vue';
+
+import { Page } from '@vben/common-ui';
+
+import { Card } from 'ant-design-vue';
+
+import { useVbenForm } from '#/adapter/form';
+
+import DocButton from '../doc-button.vue';
+
+const [CustomLayoutForm] = useVbenForm({
+  // 所有表单项共用,可单独在表单内覆盖
+  commonConfig: {
+    // 所有表单项
+    componentProps: {
+      class: 'w-full',
+    },
+  },
+  layout: 'horizontal',
+  schema: [
+    {
+      component: 'Select',
+      fieldName: 'field1',
+      label: '字符串',
+    },
+    {
+      component: 'TreeSelect',
+      fieldName: 'field2',
+      label: '字符串',
+    },
+    {
+      component: 'Mentions',
+      fieldName: 'field3',
+      label: '字符串',
+    },
+    {
+      component: 'Input',
+      fieldName: 'field4',
+      label: '字符串',
+    },
+    {
+      component: 'InputNumber',
+      fieldName: 'field5',
+      // 从第三列开始 相当于中间空了一列
+      formItemClass: 'col-start-3',
+      label: '前面空了一列',
+    },
+    {
+      component: 'Divider',
+      fieldName: '_divider',
+      formItemClass: 'col-span-3',
+      hideLabel: true,
+      renderComponentContent: () => {
+        return {
+          default: () => h('div', '分割线'),
+        };
+      },
+    },
+    {
+      component: 'Textarea',
+      fieldName: 'field6',
+      // 占满三列空间 基线对齐
+      formItemClass: 'col-span-3 items-baseline',
+      label: '占满三列',
+    },
+    {
+      component: 'Input',
+      fieldName: 'field7',
+      // 占满2列空间 从第二列开始 相当于前面空了一列
+      formItemClass: 'col-span-2 col-start-2',
+      label: '占满2列',
+    },
+    {
+      component: 'Input',
+      fieldName: 'field8',
+      // 左右留空
+      formItemClass: 'col-start-2',
+      label: '左右留空',
+    },
+    {
+      component: 'InputPassword',
+      fieldName: 'field9',
+      formItemClass: 'col-start-1',
+      label: '字符串',
+    },
+  ],
+  // 一共三列
+  wrapperClass: 'grid-cols-3',
+});
+</script>
+
+<template>
+  <Page
+    content-class="flex flex-col gap-4"
+    description="使用tailwind自定义表单项的布局"
+    title="表单自定义布局"
+  >
+    <template #description>
+      <div class="text-muted-foreground">
+        <p>使用tailwind自定义表单项的布局,使用Divider分割表单。</p>
+      </div>
+    </template>
+    <template #extra>
+      <DocButton class="mb-2" path="/components/common-ui/vben-form" />
+    </template>
+    <Card title="使用tailwind自定义布局">
+      <CustomLayoutForm />
+    </Card>
+  </Page>
+</template>

+ 3 - 1
playground/src/views/examples/form/rules.vue

@@ -150,7 +150,9 @@ const [Form, formApi] = useVbenForm({
           default: () => ['我已阅读并同意'],
         };
       },
-      rules: 'selectRequired',
+      rules: z.boolean().refine((value) => value, {
+        message: '请勾选',
+      }),
     },
     {
       component: 'DatePicker',