Browse Source

fix: fix the form-api reactive failure inside the form (#4590)

* fix: fix the form-api reactive failure inside the form
Vben 5 months ago
parent
commit
2dbd323b2a

+ 1 - 0
packages/effects/plugins/package.json

@@ -34,6 +34,7 @@
     "@vben/types": "workspace:*",
     "@vben/utils": "workspace:*",
     "@vueuse/core": "catalog:",
+    "dayjs": "catalog:",
     "echarts": "catalog:",
     "vue": "catalog:",
     "vxe-pc-ui": "catalog:",

+ 17 - 0
packages/effects/plugins/src/vxe-table/formatter.ts

@@ -0,0 +1,17 @@
+import type { VxeUIExport } from 'vxe-table';
+
+import dayjs from 'dayjs';
+
+export function initDefaultFormatter(vxeUI: VxeUIExport) {
+  vxeUI.formats.add('formatDate', {
+    tableCellFormatMethod({ cellValue }) {
+      return dayjs(cellValue).format('YYYY-MM-DD');
+    },
+  });
+
+  vxeUI.formats.add('formatDateTime', {
+    tableCellFormatMethod({ cellValue }) {
+      return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss');
+    },
+  });
+}

+ 3 - 0
packages/effects/plugins/src/vxe-table/init.ts

@@ -41,6 +41,8 @@ import {
   VxeToolbar,
 } from 'vxe-table';
 
+import { initDefaultFormatter } from './formatter';
+
 // 是否加载过
 let isInit = false;
 
@@ -118,5 +120,6 @@ export function setupVbenVxeTable(setupOptions: SetupVxeTable) {
     },
   );
 
+  initDefaultFormatter(VxeUI);
   configVxeTable(VxeUI);
 }

+ 44 - 36
packages/effects/plugins/src/vxe-table/use-vxe-grid.vue

@@ -14,6 +14,7 @@ import {
   toRaw,
   useSlots,
   useTemplateRef,
+  watch,
 } from 'vue';
 
 import { usePriorityValues } from '@vben/hooks';
@@ -53,7 +54,27 @@ const { isMobile } = usePreferences();
 
 const slots = useSlots();
 
-const [Form, formApi] = useTableForm({});
+const [Form, formApi] = useTableForm({
+  handleSubmit: async () => {
+    const formValues = formApi.form.values;
+    props.api.reload(formValues);
+  },
+  handleReset: async () => {
+    await formApi.resetForm();
+    const formValues = formApi.form.values;
+    props.api.reload(formValues);
+  },
+  commonConfig: {
+    componentProps: {
+      class: 'w-full',
+    },
+  },
+  showCollapseButton: true,
+  submitButtonOptions: {
+    content: $t('common.query'),
+  },
+  wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
+});
 
 const showToolbar = computed(() => {
   return !!slots['toolbar-actions']?.() || !!slots['toolbar-tools']?.();
@@ -136,40 +157,6 @@ const events = computed(() => {
   };
 });
 
-const vbenFormOptions = computed(() => {
-  const defaultFormProps: VbenFormProps = {
-    handleSubmit: async () => {
-      const formValues = formApi.form.values;
-      props.api.reload(formValues);
-    },
-    handleReset: async () => {
-      await formApi.resetForm();
-      const formValues = formApi.form.values;
-      props.api.reload(formValues);
-    },
-    commonConfig: {
-      componentProps: {
-        class: 'w-full',
-      },
-    },
-    showCollapseButton: true,
-    submitButtonOptions: {
-      content: $t('common.query'),
-    },
-    wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
-  };
-  const finalFormOptions: VbenFormProps = mergeWithArrayOverride(
-    {},
-    formOptions.value,
-    defaultFormProps,
-  );
-
-  return {
-    ...finalFormOptions,
-    collapseTriggerResize: !!finalFormOptions.showCollapseButton,
-  };
-});
-
 const delegatedSlots = computed(() => {
   const resultSlots: string[] = [];
 
@@ -215,6 +202,27 @@ async function init() {
     );
   }
 }
+
+watch(
+  formOptions,
+  () => {
+    formApi.setState((prev) => {
+      const finalFormOptions: VbenFormProps = mergeWithArrayOverride(
+        {},
+        formOptions.value,
+        prev,
+      );
+      return {
+        ...finalFormOptions,
+        collapseTriggerResize: !!finalFormOptions.showCollapseButton,
+      };
+    });
+  },
+  {
+    immediate: true,
+  },
+);
+
 onMounted(() => {
   props.api?.mount?.(gridRef.value, formApi);
   init();
@@ -247,7 +255,7 @@ onMounted(() => {
       <template #form>
         <div v-if="formOptions" class="relative rounded py-3 pb-4">
           <slot name="form">
-            <Form v-bind="vbenFormOptions">
+            <Form>
               <template
                 v-for="slotName in delegatedFormSlots"
                 :key="slotName"

+ 1 - 4
playground/src/views/examples/vxe-table/custom-cell.vue

@@ -4,7 +4,6 @@ import type { VxeGridProps } from '#/adapter';
 import { Page } from '@vben/common-ui';
 
 import { Button, Image, Switch, Tag } from 'ant-design-vue';
-import dayjs from 'dayjs';
 
 import { useVbenVxeGrid } from '#/adapter';
 import { getExampleTableApi } from '#/api';
@@ -58,9 +57,7 @@ const gridOptions: VxeGridProps<RowType> = {
     { field: 'price', title: 'Price', width: 100 },
     {
       field: 'releaseDate',
-      formatter: ({ cellValue }) => {
-        return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss');
-      },
+      formatter: 'formatDateTime',
       title: 'Date',
       width: 200,
     },

+ 1 - 1
playground/src/views/examples/vxe-table/edit-cell.vue

@@ -26,7 +26,7 @@ const gridOptions: VxeGridProps<RowType> = {
       title: 'Product Name',
     },
     { field: 'price', title: 'Price' },
-    { field: 'releaseDate', title: 'Date' },
+    { field: 'releaseDate', formatter: 'formatDateTime', title: 'Date' },
   ],
   editConfig: {
     mode: 'cell',

+ 1 - 1
playground/src/views/examples/vxe-table/edit-row.vue

@@ -28,7 +28,7 @@ const gridOptions: VxeGridProps<RowType> = {
       title: 'Product Name',
     },
     { field: 'price', title: 'Price' },
-    { field: 'releaseDate', title: 'Date' },
+    { field: 'releaseDate', formatter: 'formatDateTime', title: 'Date' },
     { slots: { default: 'action' }, title: '操作' },
   ],
   editConfig: {

+ 12 - 1
playground/src/views/examples/vxe-table/fixed.vue

@@ -24,7 +24,18 @@ const gridOptions: VxeGridProps<RowType> = {
     { field: 'color', title: 'Color', width: 300 },
     { field: 'productName', title: 'Product Name', width: 300 },
     { field: 'price', title: 'Price', width: 300 },
-    { field: 'releaseDate', title: 'Date', width: 500 },
+    {
+      field: 'releaseDate',
+      formatter: 'formatDateTime',
+      title: 'DateTime',
+      width: 500,
+    },
+    {
+      field: 'releaseDate',
+      formatter: 'formatDate',
+      title: 'Date',
+      width: 300,
+    },
     {
       field: 'action',
       fixed: 'right',

+ 7 - 8
playground/src/views/examples/vxe-table/form.vue

@@ -18,6 +18,7 @@ interface RowType {
 }
 
 const formOptions: VbenFormProps = {
+  collapsed: true,
   schema: [
     {
       component: 'Input',
@@ -73,7 +74,7 @@ const gridOptions: VxeGridProps<RowType> = {
     { field: 'color', title: 'Color' },
     { field: 'productName', title: 'Product Name' },
     { field: 'price', title: 'Price' },
-    { field: 'releaseDate', title: 'Date' },
+    { field: 'releaseDate', formatter: 'formatDateTime', title: 'Date' },
   ],
   height: 'auto',
   keepSource: true,
@@ -95,13 +96,11 @@ const gridOptions: VxeGridProps<RowType> = {
 const [Grid, gridApi] = useVbenVxeGrid({ formOptions, gridOptions });
 
 function toggleFormCollspae() {
-  gridApi.formApi.resetForm();
-  gridApi.setState({
-    formOptions: {
-      showCollapseButton: !(
-        gridApi.state?.formOptions?.showCollapseButton ?? true
-      ),
-    },
+  gridApi.formApi.setState((prev) => {
+    return {
+      ...prev,
+      showCollapseButton: !prev.showCollapseButton,
+    };
   });
 }
 </script>

+ 2 - 1
playground/src/views/examples/vxe-table/remote.vue

@@ -29,7 +29,8 @@ const gridOptions: VxeGridProps<RowType> = {
     { field: 'color', title: 'Color' },
     { field: 'productName', title: 'Product Name' },
     { field: 'price', title: 'Price' },
-    { field: 'releaseDate', title: 'Date' },
+    { field: 'releaseDate', formatter: 'formatDateTime', title: 'DateTime' },
+    { field: 'releaseDate', formatter: 'formatDate', title: 'Date' },
   ],
   height: 'auto',
   keepSource: true,

+ 62 - 35
pnpm-lock.yaml

@@ -55,8 +55,8 @@ catalogs:
       specifier: ^2.5.0
       version: 2.5.0
     '@playwright/test':
-      specifier: ^1.47.2
-      version: 1.47.2
+      specifier: ^1.48.0
+      version: 1.48.0
     '@stylistic/stylelint-plugin':
       specifier: ^3.1.1
       version: 3.1.1
@@ -295,8 +295,8 @@ catalogs:
       specifier: ^4.5.0
       version: 4.5.0
     lucide-vue-next:
-      specifier: ^0.447.0
-      version: 0.447.0
+      specifier: ^0.451.0
+      version: 0.451.0
     medium-zoom:
       specifier: ^1.1.0
       version: 1.1.0
@@ -319,11 +319,11 @@ catalogs:
       specifier: ^4.1.1
       version: 4.1.1
     pkg-types:
-      specifier: ^1.2.0
-      version: 1.2.0
+      specifier: ^1.2.1
+      version: 1.2.1
     playwright:
-      specifier: ^1.47.2
-      version: 1.47.2
+      specifier: ^1.48.0
+      version: 1.48.0
     postcss:
       specifier: ^8.4.47
       version: 8.4.47
@@ -475,8 +475,8 @@ catalogs:
       specifier: ^2.1.6
       version: 2.1.6
     vxe-pc-ui:
-      specifier: ^4.2.16
-      version: 4.2.16
+      specifier: ^4.2.18
+      version: 4.2.18
     vxe-table:
       specifier: ^4.7.86
       version: 4.7.86
@@ -508,7 +508,7 @@ importers:
         version: 2.27.9
       '@playwright/test':
         specifier: 'catalog:'
-        version: 1.47.2
+        version: 1.48.0
       '@types/node':
         specifier: 'catalog:'
         version: 22.7.5
@@ -571,7 +571,7 @@ importers:
         version: 15.2.10
       playwright:
         specifier: 'catalog:'
-        version: 1.47.2
+        version: 1.48.0
       rimraf:
         specifier: 'catalog:'
         version: 6.0.1
@@ -828,7 +828,7 @@ importers:
         version: 4.2.5(vue@3.5.11(typescript@5.6.2))
       lucide-vue-next:
         specifier: 'catalog:'
-        version: 0.447.0(vue@3.5.11(typescript@5.6.2))
+        version: 0.451.0(vue@3.5.11(typescript@5.6.2))
       medium-zoom:
         specifier: 'catalog:'
         version: 1.1.0
@@ -1035,7 +1035,7 @@ importers:
         version: 8.1.0
       pkg-types:
         specifier: 'catalog:'
-        version: 1.2.0
+        version: 1.2.1
       prettier:
         specifier: 'catalog:'
         version: 3.3.3
@@ -1193,7 +1193,7 @@ importers:
         version: 4.1.2(vue@3.5.11(typescript@5.6.2))
       lucide-vue-next:
         specifier: 'catalog:'
-        version: 0.447.0(vue@3.5.11(typescript@5.6.2))
+        version: 0.451.0(vue@3.5.11(typescript@5.6.2))
       vue:
         specifier: ^3.5.11
         version: 3.5.11(typescript@5.6.2)
@@ -1402,7 +1402,7 @@ importers:
         version: 0.7.0
       lucide-vue-next:
         specifier: 'catalog:'
-        version: 0.447.0(vue@3.5.11(typescript@5.6.2))
+        version: 0.451.0(vue@3.5.11(typescript@5.6.2))
       radix-vue:
         specifier: 'catalog:'
         version: 1.9.7(vue@3.5.11(typescript@5.6.2))
@@ -1626,6 +1626,9 @@ importers:
       '@vueuse/core':
         specifier: 'catalog:'
         version: 11.1.0(vue@3.5.11(typescript@5.6.2))
+      dayjs:
+        specifier: 'catalog:'
+        version: 1.11.13
       echarts:
         specifier: 'catalog:'
         version: 5.5.1
@@ -1634,7 +1637,7 @@ importers:
         version: 3.5.11(typescript@5.6.2)
       vxe-pc-ui:
         specifier: 'catalog:'
-        version: 4.2.16
+        version: 4.2.18
       vxe-table:
         specifier: 'catalog:'
         version: 4.7.86
@@ -4240,8 +4243,8 @@ packages:
     resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==}
     engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
 
-  '@playwright/test@1.47.2':
-    resolution: {integrity: sha512-jTXRsoSPONAs8Za9QEQdyjFn+0ZQFjCiIztAIF6bi1HqhBzG9Ma7g1WotyiGqFSBRZjIEqMdT8RUlbk1QVhzCQ==}
+  '@playwright/test@1.48.0':
+    resolution: {integrity: sha512-W5lhqPUVPqhtc/ySvZI5Q8X2ztBOUgZ8LbAFy0JQgrXZs2xaILrUcNO3rQjwbLPfGK13+rZsDa1FpG+tqYkT5w==}
     engines: {node: '>=18'}
     hasBin: true
 
@@ -5612,6 +5615,9 @@ packages:
   confbox@0.1.7:
     resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==}
 
+  confbox@0.1.8:
+    resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
+
   config-chain@1.1.13:
     resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==}
 
@@ -7644,8 +7650,8 @@ packages:
     resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
     engines: {node: '>=10'}
 
-  lucide-vue-next@0.447.0:
-    resolution: {integrity: sha512-NXD61EHwgdIHZsVxFGYHowrPZnhWJOByVJ23LJB28BnXII29Cg157DmIbvrJ7idwbfhwYhCZ2moRfKOCwIvNiw==}
+  lucide-vue-next@0.451.0:
+    resolution: {integrity: sha512-EJ3tDuZqFdps6wt4hhqJ/EzCE7KbhClkncvnqXiVE6Ni5jzA5XS1Ut5yCGXjO/GBIe39t3qmNRQIRszqdCDuBA==}
     peerDependencies:
       vue: ^3.5.11
 
@@ -7851,6 +7857,9 @@ packages:
   mlly@1.7.1:
     resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==}
 
+  mlly@1.7.2:
+    resolution: {integrity: sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==}
+
   mri@1.2.0:
     resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
     engines: {node: '>=4'}
@@ -8286,13 +8295,16 @@ packages:
   pkg-types@1.2.0:
     resolution: {integrity: sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==}
 
-  playwright-core@1.47.2:
-    resolution: {integrity: sha512-3JvMfF+9LJfe16l7AbSmU555PaTl2tPyQsVInqm3id16pdDfvZ8TTZ/pyzmkbDrZTQefyzU7AIHlZqQnxpqHVQ==}
+  pkg-types@1.2.1:
+    resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==}
+
+  playwright-core@1.48.0:
+    resolution: {integrity: sha512-RBvzjM9rdpP7UUFrQzRwR8L/xR4HyC1QXMzGYTbf1vjw25/ya9NRAVnXi/0fvFopjebvyPzsmoK58xxeEOaVvA==}
     engines: {node: '>=18'}
     hasBin: true
 
-  playwright@1.47.2:
-    resolution: {integrity: sha512-nx1cLMmQWqmA3UsnjaaokyoUpdVaaDhJhMoxX2qj3McpjnsqFHs516QAKYhqHAgOP+oCFTEOCOAaD1RgD/RQfA==}
+  playwright@1.48.0:
+    resolution: {integrity: sha512-qPqFaMEHuY/ug8o0uteYJSRfMGFikhUysk8ZvAtfKmUK3kc/6oNl/y3EczF8OFGYIi/Ex2HspMfzYArk6+XQSA==}
     engines: {node: '>=18'}
     hasBin: true
 
@@ -10254,8 +10266,8 @@ packages:
     peerDependencies:
       vue: ^3.5.11
 
-  vxe-pc-ui@4.2.16:
-    resolution: {integrity: sha512-gq6GXKnEPyxzIQx4T4LNtt15kl3KZqq+U11c4MniPK/9QOUuRva1oEocvMXAFtz17aL1zLDXrAq2rmrbebDHVQ==}
+  vxe-pc-ui@4.2.18:
+    resolution: {integrity: sha512-OfS3h7YitqwGCk4ILMUyFTBEtXnv3DnTvT7R2DYjG9O1fr6tY2EbRfnpaMMKUCfSHbq/7AyOJJNJz7/g6u8ucw==}
 
   vxe-table@4.7.86:
     resolution: {integrity: sha512-7VJjOb/jZf6JMobFER6ZfJI6Mt5L7N85dEOSLR20ZXwfSxRF6vfkXb7kAvuZ4FOXJxT2D7yaAEICPZHPCwwp4g==}
@@ -13122,9 +13134,9 @@ snapshots:
 
   '@pkgr/core@0.1.1': {}
 
-  '@playwright/test@1.47.2':
+  '@playwright/test@1.48.0':
     dependencies:
-      playwright: 1.47.2
+      playwright: 1.48.0
 
   '@pnpm/config.env-replace@1.1.0': {}
 
@@ -14762,6 +14774,8 @@ snapshots:
 
   confbox@0.1.7: {}
 
+  confbox@0.1.8: {}
+
   config-chain@1.1.13:
     dependencies:
       ini: 1.3.8
@@ -17045,7 +17059,7 @@ snapshots:
     dependencies:
       yallist: 4.0.0
 
-  lucide-vue-next@0.447.0(vue@3.5.11(typescript@5.6.2)):
+  lucide-vue-next@0.451.0(vue@3.5.11(typescript@5.6.2)):
     dependencies:
       vue: 3.5.11(typescript@5.6.2)
 
@@ -17260,6 +17274,13 @@ snapshots:
       pkg-types: 1.2.0
       ufo: 1.5.4
 
+  mlly@1.7.2:
+    dependencies:
+      acorn: 8.12.1
+      pathe: 1.1.2
+      pkg-types: 1.2.1
+      ufo: 1.5.4
+
   mri@1.2.0: {}
 
   mrmime@2.0.0: {}
@@ -17772,11 +17793,17 @@ snapshots:
       mlly: 1.7.1
       pathe: 1.1.2
 
-  playwright-core@1.47.2: {}
+  pkg-types@1.2.1:
+    dependencies:
+      confbox: 0.1.8
+      mlly: 1.7.2
+      pathe: 1.1.2
+
+  playwright-core@1.48.0: {}
 
-  playwright@1.47.2:
+  playwright@1.48.0:
     dependencies:
-      playwright-core: 1.47.2
+      playwright-core: 1.48.0
     optionalDependencies:
       fsevents: 2.3.2
 
@@ -19942,13 +19969,13 @@ snapshots:
       vooks: 0.2.12(vue@3.5.11(typescript@5.6.2))
       vue: 3.5.11(typescript@5.6.2)
 
-  vxe-pc-ui@4.2.16:
+  vxe-pc-ui@4.2.18:
     dependencies:
       '@vxe-ui/core': 4.0.13
 
   vxe-table@4.7.86:
     dependencies:
-      vxe-pc-ui: 4.2.16
+      vxe-pc-ui: 4.2.18
 
   warning@4.0.3:
     dependencies:

+ 5 - 5
pnpm-workspace.yaml

@@ -30,7 +30,7 @@ catalog:
   '@jspm/generator': ^2.3.1
   '@manypkg/get-packages': ^2.2.2
   '@nolebase/vitepress-plugin-git-changelog': ^2.5.0
-  '@playwright/test': ^1.47.2
+  '@playwright/test': ^1.48.0
   '@stylistic/stylelint-plugin': ^3.1.1
   '@tailwindcss/nesting': 0.0.0-insiders.565cd3e
   '@tailwindcss/typography': ^0.5.15
@@ -111,7 +111,7 @@ catalog:
   jsonwebtoken: ^9.0.2
   lint-staged: ^15.2.10
   lodash.clonedeep: ^4.5.0
-  lucide-vue-next: ^0.447.0
+  lucide-vue-next: ^0.451.0
   medium-zoom: ^1.1.0
   naive-ui: ^2.40.1
   nanoid: ^5.0.7
@@ -120,8 +120,8 @@ catalog:
   ora: ^8.1.0
   pinia: 2.2.2
   pinia-plugin-persistedstate: ^4.1.1
-  pkg-types: ^1.2.0
-  playwright: ^1.47.2
+  pkg-types: ^1.2.1
+  playwright: ^1.48.0
   postcss: ^8.4.47
   postcss-antd-fixes: ^0.2.0
   postcss-html: ^1.7.0
@@ -173,7 +173,7 @@ catalog:
   vue-i18n: ^10.0.4
   vue-router: ^4.4.5
   vue-tsc: ^2.1.6
-  vxe-pc-ui: ^4.2.16
+  vxe-pc-ui: ^4.2.18
   vxe-table: ^4.7.86
   watermark-js-plus: ^1.5.7
   zod: ^3.23.8