diff --git a/.vscode/settings.json b/.vscode/settings.json index 2efb27ce..62dc9828 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -160,6 +160,7 @@ "stylelint.enable": true, "stylelint.packageManager": "pnpm", "stylelint.validate": ["css", "less", "postcss", "scss", "vue"], + "stylelint.customSyntax": "postcss-html", "stylelint.snippet": ["css", "less", "postcss", "scss", "vue"], "typescript.inlayHints.enumMemberValues.enabled": true, diff --git a/apps/web-antd/src/adapter/vxe-table.ts b/apps/web-antd/src/adapter/vxe-table.ts index 32c03c0c..b4cc88c0 100644 --- a/apps/web-antd/src/adapter/vxe-table.ts +++ b/apps/web-antd/src/adapter/vxe-table.ts @@ -77,7 +77,7 @@ setupVbenVxeTable({ // 表格配置项可以用 cellRender: { name: 'CellImage' }, vxeUI.renderer.add('CellImage', { - renderDefault(_renderOpts, params) { + renderTableDefault(_renderOpts, params) { const { column, row } = params; return h(Image, { src: row[column.field] }); }, @@ -85,7 +85,7 @@ setupVbenVxeTable({ // 表格配置项可以用 cellRender: { name: 'CellLink' }, vxeUI.renderer.add('CellLink', { - renderDefault(renderOpts) { + renderTableDefault(renderOpts) { const { props } = renderOpts; return h( Button, diff --git a/apps/web-antd/src/bootstrap.ts b/apps/web-antd/src/bootstrap.ts index d1740e56..f842021c 100644 --- a/apps/web-antd/src/bootstrap.ts +++ b/apps/web-antd/src/bootstrap.ts @@ -1,12 +1,15 @@ -import { createApp } from 'vue'; +import { createApp, watchEffect } from 'vue'; import { registerAccessDirective } from '@vben/access'; +import { preferences } from '@vben/preferences'; import { initStores } from '@vben/stores'; import '@vben/styles'; import '@vben/styles/antd'; +import { useTitle } from '@vueuse/core'; + import { setupGlobalComponent } from '#/components/global'; -import { setupI18n } from '#/locales'; +import { $t, setupI18n } from '#/locales'; import { initComponentAdapter } from './adapter/component'; import App from './app.vue'; @@ -33,6 +36,16 @@ async function bootstrap(namespace: string) { // 配置路由及路由守卫 app.use(router); + // 动态更新标题 + watchEffect(() => { + if (preferences.app.dynamicTitle) { + const routeTitle = router.currentRoute.value.meta?.title; + const pageTitle = + (routeTitle ? `${$t(routeTitle)} - ` : '') + preferences.app.name; + useTitle(pageTitle); + } + }); + app.mount('#app'); } diff --git a/apps/web-antd/src/preferences.ts b/apps/web-antd/src/preferences.ts index 16d86d7e..4866b15e 100644 --- a/apps/web-antd/src/preferences.ts +++ b/apps/web-antd/src/preferences.ts @@ -3,6 +3,7 @@ import { defineOverridesPreferences } from '@vben/preferences'; /** * @description 项目配置文件 * 只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置 + * !!! 更改配置后请清空缓存,否则可能不生效 */ export const overridesPreferences = defineOverridesPreferences({ // overrides diff --git a/apps/web-antd/src/router/guard.ts b/apps/web-antd/src/router/guard.ts index 52edfe01..fce5a892 100644 --- a/apps/web-antd/src/router/guard.ts +++ b/apps/web-antd/src/router/guard.ts @@ -5,9 +5,6 @@ import { preferences } from '@vben/preferences'; import { useAccessStore, useUserStore } from '@vben/stores'; import { startProgress, stopProgress } from '@vben/utils'; -import { useTitle } from '@vueuse/core'; - -import { $t } from '#/locales'; import { accessRoutes, coreRouteNames } from '#/router/routes'; import { useAuthStore } from '#/store'; @@ -40,13 +37,6 @@ function setupCommonGuard(router: Router) { if (preferences.transition.progress) { stopProgress(); } - - // 动态修改标题 - if (preferences.app.dynamicTitle) { - const { title } = to.meta; - // useTitle(`${$t(title)} - ${preferences.app.name}`); - useTitle(`${$t(title)} - ${preferences.app.name}`); - } }); } diff --git a/apps/web-ele/src/adapter/vxe-table.ts b/apps/web-ele/src/adapter/vxe-table.ts index 067451e4..44b31eae 100644 --- a/apps/web-ele/src/adapter/vxe-table.ts +++ b/apps/web-ele/src/adapter/vxe-table.ts @@ -38,7 +38,7 @@ setupVbenVxeTable({ // 表格配置项可以用 cellRender: { name: 'CellImage' }, vxeUI.renderer.add('CellImage', { - renderDefault(_renderOpts, params) { + renderTableDefault(_renderOpts, params) { const { column, row } = params; const src = row[column.field]; return h(ElImage, { src, previewSrcList: [src] }); @@ -47,7 +47,7 @@ setupVbenVxeTable({ // 表格配置项可以用 cellRender: { name: 'CellLink' }, vxeUI.renderer.add('CellLink', { - renderDefault(renderOpts) { + renderTableDefault(renderOpts) { const { props } = renderOpts; return h( ElButton, diff --git a/apps/web-ele/src/bootstrap.ts b/apps/web-ele/src/bootstrap.ts index 7311d665..de188473 100644 --- a/apps/web-ele/src/bootstrap.ts +++ b/apps/web-ele/src/bootstrap.ts @@ -1,11 +1,14 @@ -import { createApp } from 'vue'; +import { createApp, watchEffect } from 'vue'; import { registerAccessDirective } from '@vben/access'; +import { preferences } from '@vben/preferences'; import { initStores } from '@vben/stores'; import '@vben/styles'; import '@vben/styles/ele'; -import { setupI18n } from '#/locales'; +import { useTitle } from '@vueuse/core'; + +import { $t, setupI18n } from '#/locales'; import { initComponentAdapter } from './adapter/component'; import App from './app.vue'; @@ -28,6 +31,16 @@ async function bootstrap(namespace: string) { // 配置路由及路由守卫 app.use(router); + // 动态更新标题 + watchEffect(() => { + if (preferences.app.dynamicTitle) { + const routeTitle = router.currentRoute.value.meta?.title; + const pageTitle = + (routeTitle ? `${$t(routeTitle)} - ` : '') + preferences.app.name; + useTitle(pageTitle); + } + }); + app.mount('#app'); } diff --git a/apps/web-ele/src/preferences.ts b/apps/web-ele/src/preferences.ts index 63edb3a9..b2e9ace4 100644 --- a/apps/web-ele/src/preferences.ts +++ b/apps/web-ele/src/preferences.ts @@ -3,6 +3,7 @@ import { defineOverridesPreferences } from '@vben/preferences'; /** * @description 项目配置文件 * 只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置 + * !!! 更改配置后请清空缓存,否则可能不生效 */ export const overridesPreferences = defineOverridesPreferences({ // overrides diff --git a/apps/web-ele/src/router/guard.ts b/apps/web-ele/src/router/guard.ts index 52edfe01..fce5a892 100644 --- a/apps/web-ele/src/router/guard.ts +++ b/apps/web-ele/src/router/guard.ts @@ -5,9 +5,6 @@ import { preferences } from '@vben/preferences'; import { useAccessStore, useUserStore } from '@vben/stores'; import { startProgress, stopProgress } from '@vben/utils'; -import { useTitle } from '@vueuse/core'; - -import { $t } from '#/locales'; import { accessRoutes, coreRouteNames } from '#/router/routes'; import { useAuthStore } from '#/store'; @@ -40,13 +37,6 @@ function setupCommonGuard(router: Router) { if (preferences.transition.progress) { stopProgress(); } - - // 动态修改标题 - if (preferences.app.dynamicTitle) { - const { title } = to.meta; - // useTitle(`${$t(title)} - ${preferences.app.name}`); - useTitle(`${$t(title)} - ${preferences.app.name}`); - } }); } diff --git a/apps/web-naive/src/adapter/vxe-table.ts b/apps/web-naive/src/adapter/vxe-table.ts index 271a5baf..081cfb29 100644 --- a/apps/web-naive/src/adapter/vxe-table.ts +++ b/apps/web-naive/src/adapter/vxe-table.ts @@ -38,7 +38,7 @@ setupVbenVxeTable({ // 表格配置项可以用 cellRender: { name: 'CellImage' }, vxeUI.renderer.add('CellImage', { - renderDefault(_renderOpts, params) { + renderTableDefault(_renderOpts, params) { const { column, row } = params; return h(NImage, { src: row[column.field] }); }, @@ -46,7 +46,7 @@ setupVbenVxeTable({ // 表格配置项可以用 cellRender: { name: 'CellLink' }, vxeUI.renderer.add('CellLink', { - renderDefault(renderOpts) { + renderTableDefault(renderOpts) { const { props } = renderOpts; return h( NButton, diff --git a/apps/web-naive/src/bootstrap.ts b/apps/web-naive/src/bootstrap.ts index 13ab95cb..fc7f961d 100644 --- a/apps/web-naive/src/bootstrap.ts +++ b/apps/web-naive/src/bootstrap.ts @@ -1,10 +1,13 @@ -import { createApp } from 'vue'; +import { createApp, watchEffect } from 'vue'; import { registerAccessDirective } from '@vben/access'; +import { preferences } from '@vben/preferences'; import { initStores } from '@vben/stores'; import '@vben/styles'; -import { setupI18n } from '#/locales'; +import { useTitle } from '@vueuse/core'; + +import { $t, setupI18n } from '#/locales'; import { initComponentAdapter } from './adapter/component'; import App from './app.vue'; @@ -27,6 +30,16 @@ async function bootstrap(namespace: string) { // 配置路由及路由守卫 app.use(router); + // 动态更新标题 + watchEffect(() => { + if (preferences.app.dynamicTitle) { + const routeTitle = router.currentRoute.value.meta?.title; + const pageTitle = + (routeTitle ? `${$t(routeTitle)} - ` : '') + preferences.app.name; + useTitle(pageTitle); + } + }); + app.mount('#app'); } diff --git a/apps/web-naive/src/preferences.ts b/apps/web-naive/src/preferences.ts index 63edb3a9..b2e9ace4 100644 --- a/apps/web-naive/src/preferences.ts +++ b/apps/web-naive/src/preferences.ts @@ -3,6 +3,7 @@ import { defineOverridesPreferences } from '@vben/preferences'; /** * @description 项目配置文件 * 只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置 + * !!! 更改配置后请清空缓存,否则可能不生效 */ export const overridesPreferences = defineOverridesPreferences({ // overrides diff --git a/apps/web-naive/src/router/guard.ts b/apps/web-naive/src/router/guard.ts index d12003c0..c95d994e 100644 --- a/apps/web-naive/src/router/guard.ts +++ b/apps/web-naive/src/router/guard.ts @@ -5,9 +5,6 @@ import { preferences } from '@vben/preferences'; import { useAccessStore, useUserStore } from '@vben/stores'; import { startProgress, stopProgress } from '@vben/utils'; -import { useTitle } from '@vueuse/core'; - -import { $t } from '#/locales'; import { accessRoutes, coreRouteNames } from '#/router/routes'; import { useAuthStore } from '#/store'; @@ -40,13 +37,6 @@ function setupCommonGuard(router: Router) { if (preferences.transition.progress) { stopProgress(); } - - // 动态修改标题 - if (preferences.app.dynamicTitle) { - const { title } = to.meta; - // useTitle(`${$t(title)} - ${preferences.app.name}`); - useTitle(`${$t(title)} - ${preferences.app.name}`); - } }); } diff --git a/docs/.vitepress/config/shared.mts b/docs/.vitepress/config/shared.mts index 14c8a666..b21f9eb7 100644 --- a/docs/.vitepress/config/shared.mts +++ b/docs/.vitepress/config/shared.mts @@ -3,7 +3,10 @@ import type { HeadConfig } from 'vitepress'; import { resolve } from 'node:path'; -import { viteArchiverPlugin } from '@vben/vite-config'; +import { + viteArchiverPlugin, + viteVxeTableImportsPlugin, +} from '@vben/vite-config'; import { GitChangelog, @@ -85,6 +88,7 @@ export const shared = defineConfig({ GitChangelogMarkdownSection(), viteArchiverPlugin({ outputDir: '.vitepress' }), groupIconVitePlugin(), + await viteVxeTableImportsPlugin(), ], server: { fs: { @@ -156,6 +160,7 @@ function pwa(): PwaOptions { registerType: 'autoUpdate', workbox: { globPatterns: ['**/*.{css,js,html,svg,png,ico,txt,woff2}'], + maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, }, }; } diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts index 5a01fab6..7d4d3dc2 100644 --- a/docs/.vitepress/theme/index.ts +++ b/docs/.vitepress/theme/index.ts @@ -15,11 +15,12 @@ import 'virtual:group-icons.css'; import '@nolebase/vitepress-plugin-git-changelog/client/style.css'; export default { - enhanceApp(ctx: EnhanceAppContext) { + async enhanceApp(ctx: EnhanceAppContext) { const { app } = ctx; app.component('VbenContributors', VbenContributors); app.component('DemoPreview', DemoPreview); app.use(NolebaseGitChangelogPlugin); + // 百度统计 initHmPlugin(); }, diff --git a/docs/package.json b/docs/package.json index 1ffb313b..d399ae08 100644 --- a/docs/package.json +++ b/docs/package.json @@ -8,12 +8,16 @@ "docs:preview": "vitepress preview" }, "imports": { - "#/*": "./src/_env/*" + "#/*": { + "node": "./src/_env/node/*", + "default": "./src/_env/*" + } }, "dependencies": { "@vben-core/shadcn-ui": "workspace:*", "@vben/common-ui": "workspace:*", "@vben/locales": "workspace:*", + "@vben/plugins": "workspace:*", "@vben/styles": "workspace:*", "ant-design-vue": "catalog:", "lucide-vue-next": "catalog:", diff --git a/docs/src/_env/adapter/index.ts b/docs/src/_env/adapter/index.ts deleted file mode 100644 index 698d687b..00000000 --- a/docs/src/_env/adapter/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './form'; diff --git a/docs/src/_env/adapter/vxe-table.ts b/docs/src/_env/adapter/vxe-table.ts new file mode 100644 index 00000000..bab7f3d3 --- /dev/null +++ b/docs/src/_env/adapter/vxe-table.ts @@ -0,0 +1,70 @@ +import { h } from 'vue'; + +import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table'; + +import { Button, Image } from 'ant-design-vue'; + +import { useVbenForm } from './form'; + +if (!import.meta.env.SSR) { + setupVbenVxeTable({ + configVxeTable: (vxeUI) => { + vxeUI.setConfig({ + grid: { + align: 'center', + border: false, + columnConfig: { + resizable: true, + }, + + formConfig: { + // 全局禁用vxe-table的表单配置,使用formOptions + enabled: false, + }, + minHeight: 180, + proxyConfig: { + autoLoad: true, + response: { + result: 'items', + total: 'total', + list: 'items', + }, + showActiveMsg: true, + showResponseMsg: false, + }, + round: true, + showOverflow: true, + size: 'small', + }, + }); + + // 表格配置项可以用 cellRender: { name: 'CellImage' }, + vxeUI.renderer.add('CellImage', { + renderTableDefault(_renderOpts, params) { + const { column, row } = params; + return h(Image, { src: row[column.field] }); + }, + }); + + // 表格配置项可以用 cellRender: { name: 'CellLink' }, + vxeUI.renderer.add('CellLink', { + renderTableDefault(renderOpts) { + const { props } = renderOpts; + return h( + Button, + { size: 'small', type: 'link' }, + { default: () => props?.text }, + ); + }, + }); + + // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化 + // vxeUI.formats.add + }, + useVbenForm, + }); +} + +export { useVbenVxeGrid }; + +export type * from '@vben/plugins/vxe-table'; diff --git a/docs/src/_env/node/adapter/form.ts b/docs/src/_env/node/adapter/form.ts new file mode 100644 index 00000000..a206c0d8 --- /dev/null +++ b/docs/src/_env/node/adapter/form.ts @@ -0,0 +1,4 @@ +export const useVbenForm = () => {}; +export const z = {}; +export type VbenFormSchema = any; +export type VbenFormProps = any; diff --git a/docs/src/_env/node/adapter/vxe-table.ts b/docs/src/_env/node/adapter/vxe-table.ts new file mode 100644 index 00000000..5ec409fb --- /dev/null +++ b/docs/src/_env/node/adapter/vxe-table.ts @@ -0,0 +1,3 @@ +export type * from '@vben/plugins/vxe-table'; + +export const useVbenVxeGrid = () => {}; diff --git a/docs/src/components/common-ui/vben-vxe-table.md b/docs/src/components/common-ui/vben-vxe-table.md index a80ef585..7ff8e7b2 100644 --- a/docs/src/components/common-ui/vben-vxe-table.md +++ b/docs/src/components/common-ui/vben-vxe-table.md @@ -4,4 +4,237 @@ outline: deep # Vben Vxe Table 表格 -文档待补充,如果需要使用,可先行查看 vxe-table 文档和 示例代码,内部有部分注释。 +框架提供的Table 列表组件基于 [vxe-table](https://vxetable.cn/v4/#/grid/api?apiKey=grid),结合`Vben Form 表单`进行了二次封装。 + +其中,表头的 **表单搜索** 部分采用了`Vben Form表单`,表格主体部分使用了`vxe-grid`组件,支持表格的分页、排序、筛选等功能。 + +> 如果文档内没有参数说明,可以尝试在在线示例或者在 [vxe-grid 官方API 文档](https://vxetable.cn/v4/#/grid/api?apiKey=grid) 内寻找 + +::: info 写在前面 + +如果你觉得现有组件的封装不够理想,或者不完全符合你的需求,大可以直接使用原生组件,亦或亲手封装一个适合的组件。框架提供的组件并非束缚,使用与否,完全取决于你的需求与自由。 + +::: + +## 适配器 + +表格底层使用 [vxe-table](https://vxetable.cn/#/start/install) 进行实现,所以你可以使用 `vxe-table` 的所有功能。对于不同的 UI 框架,我们提供了适配器,以便更好的适配不同的 UI 框架。 + +### 适配器说明 + +每个应用都可以自己配置`vxe-table`的适配器,你可以根据自己的需求。下面是一个简单的配置示例: + +::: details vxe-table 表格适配器 + +```ts +import { h } from 'vue'; + +import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table'; + +import { Button, Image } from 'ant-design-vue'; + +import { useVbenForm } from './form'; + +setupVbenVxeTable({ + configVxeTable: (vxeUI) => { + vxeUI.setConfig({ + grid: { + align: 'center', + border: false, + columnConfig: { + resizable: true, + }, + minHeight: 180, + formConfig: { + // 全局禁用vxe-table的表单配置,使用formOptions + enabled: false, + }, + proxyConfig: { + autoLoad: true, + response: { + result: 'items', + total: 'total', + list: 'items', + }, + showActiveMsg: true, + showResponseMsg: false, + }, + round: true, + showOverflow: true, + size: 'small', + }, + }); + + // 表格配置项可以用 cellRender: { name: 'CellImage' }, + vxeUI.renderer.add('CellImage', { + renderTableDefault(_renderOpts, params) { + const { column, row } = params; + return h(Image, { src: row[column.field] }); + }, + }); + + // 表格配置项可以用 cellRender: { name: 'CellLink' }, + vxeUI.renderer.add('CellLink', { + renderTableDefault(renderOpts) { + const { props } = renderOpts; + return h( + Button, + { size: 'small', type: 'link' }, + { default: () => props?.text }, + ); + }, + }); + + // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化 + // vxeUI.formats.add + }, + useVbenForm, +}); + +export { useVbenVxeGrid }; + +export type * from '@vben/plugins/vxe-table'; +``` + +::: + +## 基础表格 + +使用 `useVbenVxeGrid` 创建最基础的表格。 + + + +## 远程加载 + +通过指定 `proxyConfig.ajax` 的 `query` 方法,可以实现远程加载数据。 + + + +## 树形表格 + +树形表格,的数据源为扁平结构,可以指定`treeConfig`配置项,实现树形表格。 + +```typescript +treeConfig: { + transform: true, // 指定表格为树形表格 + parentField: 'parentId', // 父节点字段名 + rowField: 'id', // 行数据字段名 +}, +``` + + + +## 固定表头/列 + +列固定可选参数: `'left' | 'right' | '' | null` + + + +## 自定义单元格 + +自定义单元格有两种实现方式 + +- 通过 `slots` 插槽 +- 通过 `customCell` 自定义单元格,但是要先添加渲染器 + +```typescript +// 表格配置项可以用 cellRender: { name: 'CellImage' }, +vxeUI.renderer.add('CellImage', { + renderDefault(_renderOpts, params) { + const { column, row } = params; + return h(Image, { src: row[column.field] } as any); // 注意此处的Image 组件,来源于Antd,需要自行引入,否则会使用js的Image类 + }, +}); + +// 表格配置项可以用 cellRender: { name: 'CellLink' }, +vxeUI.renderer.add('CellLink', { + renderDefault(renderOpts) { + const { props } = renderOpts; + return h( + Button, + { size: 'small', type: 'link' }, + { default: () => props?.text }, + ); + }, +}); +``` + + + +## 搜索表单 + +**表单搜索** 部分采用了`Vben Form 表单`,参考 [Vben Form 表单文档](/components/common-ui/vben-form)。 + + + +## 单元格编辑 + +通过指定`editConfig.mode`为`cell`,可以实现单元格编辑。 + + + +## 行编辑 + +通过指定`editConfig.mode`为`row`,可以实现行编辑。 + + + +## 虚拟滚动 + +通过 scroll-y.enabled 与 scroll-y.gt 组合开启,其中 enabled 为总开关,gt 是指当总行数大于指定行数时自动开启。 + +> 参考 [vxe-table 官方文档 - 虚拟滚动](https://vxetable.cn/v4/#/component/grid/scroll/vertical)。 + + + +## API + +`useVbenVxeGrid` 返回一个数组,第一个元素是表格组件,第二个元素是表格的方法。 + +```vue + + + +``` + +### GridApi + +useVbenVxeGrid 返回的第二个参数,是一个对象,包含了一些表单的方法。 + +| 方法名 | 描述 | 类型 | +| --- | --- | --- | +| setLoading | 设置loading状态 | `(loading)=>void` | +| setGridOptions | 设置vxe-table grid组件参数 | `(options: Partialvoid` | +| reload | 重载表格,会进行初始化 | `(params:any)=>void` | +| query | 重载表格,会保留当前分页 | `(params:any)=>void` | +| grid | vxe-table grid实例 | `VxeGridInstance` | +| formApi | vbenForm api实例 | `FormApi` | + +### Props + +## Props + +所有属性都可以传入 `useVbenVxeGrid` 的第一个参数中。 + +| 属性名 | 描述 | 类型 | +| -------------- | ------------------ | ------------------- | +| tableTitle | 表格标题 | `string` | +| tableTitleHelp | 表格标题帮助信息 | `string` | +| gridClass | grid组件的class | `string` | +| gridOptions | grid组件的参数 | `VxeTableGridProps` | +| gridEvents | grid组件的触发的⌚️ | `VxeGridListeners` | +| formOptions | 表单参数 | `VbenFormProps` | diff --git a/docs/src/demos/vben-vxe-table/basic/index.vue b/docs/src/demos/vben-vxe-table/basic/index.vue new file mode 100644 index 00000000..4b6b5a63 --- /dev/null +++ b/docs/src/demos/vben-vxe-table/basic/index.vue @@ -0,0 +1,85 @@ + + + diff --git a/docs/src/demos/vben-vxe-table/custom-cell/index.vue b/docs/src/demos/vben-vxe-table/custom-cell/index.vue new file mode 100644 index 00000000..517e73f3 --- /dev/null +++ b/docs/src/demos/vben-vxe-table/custom-cell/index.vue @@ -0,0 +1,105 @@ + + + diff --git a/docs/src/demos/vben-vxe-table/edit-cell/index.vue b/docs/src/demos/vben-vxe-table/edit-cell/index.vue new file mode 100644 index 00000000..711941de --- /dev/null +++ b/docs/src/demos/vben-vxe-table/edit-cell/index.vue @@ -0,0 +1,55 @@ + + + diff --git a/docs/src/demos/vben-vxe-table/edit-row/index.vue b/docs/src/demos/vben-vxe-table/edit-row/index.vue new file mode 100644 index 00000000..f317f69d --- /dev/null +++ b/docs/src/demos/vben-vxe-table/edit-row/index.vue @@ -0,0 +1,92 @@ + + + diff --git a/docs/src/demos/vben-vxe-table/fixed/index.vue b/docs/src/demos/vben-vxe-table/fixed/index.vue new file mode 100644 index 00000000..6067a5eb --- /dev/null +++ b/docs/src/demos/vben-vxe-table/fixed/index.vue @@ -0,0 +1,67 @@ + + + diff --git a/docs/src/demos/vben-vxe-table/form/index.vue b/docs/src/demos/vben-vxe-table/form/index.vue new file mode 100644 index 00000000..a5e8a547 --- /dev/null +++ b/docs/src/demos/vben-vxe-table/form/index.vue @@ -0,0 +1,120 @@ + + + diff --git a/docs/src/demos/vben-vxe-table/mock-api.ts b/docs/src/demos/vben-vxe-table/mock-api.ts new file mode 100644 index 00000000..e5c40b61 --- /dev/null +++ b/docs/src/demos/vben-vxe-table/mock-api.ts @@ -0,0 +1,36 @@ +import { MOCK_API_DATA } from './table-data'; + +export namespace DemoTableApi { + export interface PageFetchParams { + [key: string]: any; + page: number; + pageSize: number; + } +} + +export function sleep(time = 1000) { + return new Promise((resolve) => { + setTimeout(() => { + resolve(true); + }, time); + }); +} + +/** + * 获取示例表格数据 + */ +async function getExampleTableApi(params: DemoTableApi.PageFetchParams) { + return new Promise<{ items: any; total: number }>((resolve) => { + const { page, pageSize } = params; + const items = MOCK_API_DATA.slice((page - 1) * pageSize, page * pageSize); + + sleep(1000).then(() => { + resolve({ + total: items.length, + items, + }); + }); + }); +} + +export { getExampleTableApi }; diff --git a/docs/src/demos/vben-vxe-table/remote/index.vue b/docs/src/demos/vben-vxe-table/remote/index.vue new file mode 100644 index 00000000..bc93d29a --- /dev/null +++ b/docs/src/demos/vben-vxe-table/remote/index.vue @@ -0,0 +1,112 @@ + + + diff --git a/docs/src/demos/vben-vxe-table/table-data.ts b/docs/src/demos/vben-vxe-table/table-data.ts new file mode 100644 index 00000000..c37b88ad --- /dev/null +++ b/docs/src/demos/vben-vxe-table/table-data.ts @@ -0,0 +1,384 @@ +interface TableRowData { + address: string; + age: number; + id: number; + name: string; + nickname: string; + role: string; +} + +const roles = ['User', 'Admin', 'Manager', 'Guest']; + +export const MOCK_TABLE_DATA: TableRowData[] = (() => { + const data: TableRowData[] = []; + for (let i = 0; i < 10; i++) { + data.push({ + address: `New York${i}`, + age: i + 1, + id: i, + name: `Test${i}`, + nickname: `Test${i}`, + role: roles[Math.floor(Math.random() * roles.length)] as string, + }); + } + return data; +})(); + +export const MOCK_TREE_TABLE_DATA = [ + { + date: '2020-08-01', + id: 10_000, + name: 'Test1', + parentId: null, + size: 1024, + type: 'mp3', + }, + { + date: '2021-04-01', + id: 10_050, + name: 'Test2', + parentId: null, + size: 0, + type: 'mp4', + }, + { + date: '2020-03-01', + id: 24_300, + name: 'Test3', + parentId: 10_050, + size: 1024, + type: 'avi', + }, + { + date: '2021-04-01', + id: 20_045, + name: 'Test4', + parentId: 24_300, + size: 600, + type: 'html', + }, + { + date: '2021-04-01', + id: 10_053, + name: 'Test5', + parentId: 24_300, + size: 0, + type: 'avi', + }, + { + date: '2021-10-01', + id: 24_330, + name: 'Test6', + parentId: 10_053, + size: 25, + type: 'txt', + }, + { + date: '2020-01-01', + id: 21_011, + name: 'Test7', + parentId: 10_053, + size: 512, + type: 'pdf', + }, + { + date: '2021-06-01', + id: 22_200, + name: 'Test8', + parentId: 10_053, + size: 1024, + type: 'js', + }, + { + date: '2020-11-01', + id: 23_666, + name: 'Test9', + parentId: null, + size: 2048, + type: 'xlsx', + }, + { + date: '2021-06-01', + id: 23_677, + name: 'Test10', + parentId: 23_666, + size: 1024, + type: 'js', + }, + { + date: '2021-06-01', + id: 23_671, + name: 'Test11', + parentId: 23_677, + size: 1024, + type: 'js', + }, + { + date: '2021-06-01', + id: 23_672, + name: 'Test12', + parentId: 23_677, + size: 1024, + type: 'js', + }, + { + date: '2021-06-01', + id: 23_688, + name: 'Test13', + parentId: 23_666, + size: 1024, + type: 'js', + }, + { + date: '2021-06-01', + id: 23_681, + name: 'Test14', + parentId: 23_688, + size: 1024, + type: 'js', + }, + { + date: '2021-06-01', + id: 23_682, + name: 'Test15', + parentId: 23_688, + size: 1024, + type: 'js', + }, + { + date: '2020-10-01', + id: 24_555, + name: 'Test16', + parentId: null, + size: 224, + type: 'avi', + }, + { + date: '2021-06-01', + id: 24_566, + name: 'Test17', + parentId: 24_555, + size: 1024, + type: 'js', + }, + { + date: '2021-06-01', + id: 24_577, + name: 'Test18', + parentId: 24_555, + size: 1024, + type: 'js', + }, +]; + +export const MOCK_API_DATA = [ + { + available: true, + category: 'Computers', + color: 'purple', + currency: 'NAD', + description: + 'Ergonomic executive chair upholstered in bonded black leather and PVC padded seat and back for all-day comfort and support', + id: '45a613df-227a-4907-a89f-4a7f1252ca0c', + imageUrl: 'https://avatars.githubusercontent.com/u/62715097', + imageUrl2: 'https://avatars.githubusercontent.com/u/75395683', + inProduction: false, + open: true, + price: '48.89', + productName: 'Handcrafted Steel Salad', + quantity: 70, + rating: 3.780_582_329_574_367, + releaseDate: '2024-09-09T04:06:57.793Z', + status: 'error', + tags: ['Bespoke', 'Handmade', 'Luxurious'], + weight: 1.031_015_671_912_002_5, + }, + { + available: true, + category: 'Toys', + color: 'green', + currency: 'CZK', + description: + 'The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J', + id: 'd02e5ee9-bc98-4de2-98fa-25a6567ecc19', + imageUrl: 'https://avatars.githubusercontent.com/u/51512330', + imageUrl2: 'https://avatars.githubusercontent.com/u/58698113', + inProduction: false, + open: false, + price: '68.15', + productName: 'Generic Cotton Gloves', + quantity: 3, + rating: 1.681_749_367_682_703_3, + releaseDate: '2024-06-16T09:00:36.806Z', + status: 'warning', + tags: ['Rustic', 'Handcrafted', 'Recycled'], + weight: 9.601_076_149_300_575, + }, + { + available: true, + category: 'Beauty', + color: 'teal', + currency: 'OMR', + description: + 'The Apollotech B340 is an affordable wireless mouse with reliable connectivity, 12 months battery life and modern design', + id: '2b72521c-225c-4e64-8030-611b76b10b37', + imageUrl: 'https://avatars.githubusercontent.com/u/50300075', + imageUrl2: 'https://avatars.githubusercontent.com/u/36541691', + inProduction: true, + open: true, + price: '696.94', + productName: 'Gorgeous Soft Ball', + quantity: 50, + rating: 2.361_581_777_372_057_5, + releaseDate: '2024-06-03T13:24:19.809Z', + status: 'warning', + tags: ['Gorgeous', 'Ergonomic', 'Licensed'], + weight: 8.882_340_049_286_19, + }, + { + available: true, + category: 'Games', + color: 'silver', + currency: 'SOS', + description: + 'Carbonite web goalkeeper gloves are ergonomically designed to give easy fit', + id: 'bafab694-3801-452c-b102-9eb519bd1143', + imageUrl: 'https://avatars.githubusercontent.com/u/89827115', + imageUrl2: 'https://avatars.githubusercontent.com/u/55952747', + inProduction: false, + open: false, + price: '553.84', + productName: 'Bespoke Soft Computer', + quantity: 29, + rating: 2.176_412_873_760_271_7, + releaseDate: '2024-09-17T12:16:27.034Z', + status: 'error', + tags: ['Elegant', 'Rustic', 'Recycled'], + weight: 9.653_285_869_978_038, + }, + { + available: true, + category: 'Toys', + color: 'indigo', + currency: 'BIF', + description: + 'Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals', + id: 'bf6dea6b-2a55-441d-8773-937e03d99389', + imageUrl: 'https://avatars.githubusercontent.com/u/21431092', + imageUrl2: 'https://avatars.githubusercontent.com/u/3771350', + inProduction: true, + open: true, + price: '237.39', + productName: 'Handcrafted Cotton Mouse', + quantity: 54, + rating: 4.363_265_388_265_461, + releaseDate: '2023-10-23T13:42:34.947Z', + status: 'error', + tags: ['Unbranded', 'Handmade', 'Generic'], + weight: 9.513_203_612_535_571, + }, + { + available: false, + category: 'Tools', + color: 'violet', + currency: 'TZS', + description: + 'New ABC 13 9370, 13.3, 5th Gen CoreA5-8250U, 8GB RAM, 256GB SSD, power UHD Graphics, OS 10 Home, OS Office A & J 2016', + id: '135ba6ab-32ee-4989-8189-5cfa658ef970', + imageUrl: 'https://avatars.githubusercontent.com/u/29946092', + imageUrl2: 'https://avatars.githubusercontent.com/u/23842994', + inProduction: false, + open: false, + price: '825.25', + productName: 'Awesome Bronze Ball', + quantity: 94, + rating: 4.251_159_804_726_753, + releaseDate: '2023-12-30T07:31:43.464Z', + status: 'warning', + tags: ['Handmade', 'Elegant', 'Unbranded'], + weight: 2.247_473_385_732_636_8, + }, + { + available: true, + category: 'Automotive', + color: 'teal', + currency: 'BOB', + description: 'The Football Is Good For Training And Recreational Purposes', + id: '652ef256-7d4e-48b7-976c-7afaa781ea92', + imageUrl: 'https://avatars.githubusercontent.com/u/2531904', + imageUrl2: 'https://avatars.githubusercontent.com/u/15215990', + inProduction: false, + open: false, + price: '780.49', + productName: 'Oriental Rubber Pants', + quantity: 70, + rating: 2.636_323_417_377_916, + releaseDate: '2024-02-23T23:30:49.628Z', + status: 'success', + tags: ['Unbranded', 'Elegant', 'Unbranded'], + weight: 4.812_965_858_018_838, + }, + { + available: false, + category: 'Garden', + color: 'plum', + currency: 'LRD', + description: + 'The slim & simple Maple Gaming Keyboard from Dev Byte comes with a sleek body and 7- Color RGB LED Back-lighting for smart functionality', + id: '3ea24798-6589-40cc-85f0-ab78752244a0', + imageUrl: 'https://avatars.githubusercontent.com/u/23165285', + imageUrl2: 'https://avatars.githubusercontent.com/u/14595665', + inProduction: false, + open: true, + price: '583.85', + productName: 'Handcrafted Concrete Hat', + quantity: 15, + rating: 1.371_600_527_752_802_7, + releaseDate: '2024-03-02T19:40:50.255Z', + status: 'error', + tags: ['Rustic', 'Sleek', 'Ergonomic'], + weight: 4.926_949_366_405_728_4, + }, + { + available: false, + category: 'Industrial', + color: 'salmon', + currency: 'AUD', + description: + 'The Apollotech B340 is an affordable wireless mouse with reliable connectivity, 12 months battery life and modern design', + id: '997113dd-f6e4-4acc-9790-ef554c7498d1', + imageUrl: 'https://avatars.githubusercontent.com/u/49021914', + imageUrl2: 'https://avatars.githubusercontent.com/u/4690621', + inProduction: true, + open: false, + price: '67.99', + productName: 'Generic Rubber Bacon', + quantity: 68, + rating: 4.129_840_682_128_08, + releaseDate: '2023-12-17T01:40:25.415Z', + status: 'error', + tags: ['Oriental', 'Small', 'Handcrafted'], + weight: 1.080_114_331_801_906_4, + }, + { + available: false, + category: 'Tools', + color: 'sky blue', + currency: 'NOK', + description: + 'The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J', + id: 'f697a250-6cb2-46c8-b0f7-871ab1f2fa8d', + imageUrl: 'https://avatars.githubusercontent.com/u/95928385', + imageUrl2: 'https://avatars.githubusercontent.com/u/47588244', + inProduction: false, + open: false, + price: '613.89', + productName: 'Gorgeous Frozen Ball', + quantity: 55, + rating: 1.646_947_205_998_534_6, + releaseDate: '2024-10-13T12:31:04.929Z', + status: 'warning', + tags: ['Handmade', 'Unbranded', 'Unbranded'], + weight: 9.430_690_557_758_114, + }, +]; diff --git a/docs/src/demos/vben-vxe-table/tree/index.vue b/docs/src/demos/vben-vxe-table/tree/index.vue new file mode 100644 index 00000000..0024765a --- /dev/null +++ b/docs/src/demos/vben-vxe-table/tree/index.vue @@ -0,0 +1,80 @@ + + + diff --git a/docs/src/demos/vben-vxe-table/virtual/index.vue b/docs/src/demos/vben-vxe-table/virtual/index.vue new file mode 100644 index 00000000..81fa00af --- /dev/null +++ b/docs/src/demos/vben-vxe-table/virtual/index.vue @@ -0,0 +1,64 @@ + + + diff --git a/docs/src/guide/essentials/settings.md b/docs/src/guide/essentials/settings.md index 9a64065a..e3357206 100644 --- a/docs/src/guide/essentials/settings.md +++ b/docs/src/guide/essentials/settings.md @@ -164,6 +164,7 @@ import { defineOverridesPreferences } from '@vben/preferences'; /** * @description 项目配置文件 * 只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置 + * !!! 更改配置后请清空缓存,否则可能不生效 */ export const overridesPreferences = defineOverridesPreferences({ // overrides @@ -536,5 +537,4 @@ interface Preferences { - `overridesPreferences`方法只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置。 - 任何配置项都可以覆盖,只需要在`overridesPreferences`方法内覆盖即可,不要修改默认配置文件。 - -::: +- 更改配置后请清空缓存,否则可能不生效。::: diff --git a/docs/src/guide/introduction/quick-start.md b/docs/src/guide/introduction/quick-start.md index 1d7437f9..747c5248 100644 --- a/docs/src/guide/introduction/quick-start.md +++ b/docs/src/guide/introduction/quick-start.md @@ -66,7 +66,9 @@ pnpm install ::: tip 注意 -项目只支持使用 `pnpm` 进行依赖安装,默认会使用 `corepack` 来安装指定版本的 `pnpm`。: +- 项目只支持使用 `pnpm` 进行依赖安装,默认会使用 `corepack` 来安装指定版本的 `pnpm`。: +- 如果你的网络环境无法访问npm源,你可以设置系统的环境变量`COREPACK_REGISTRY=https://registry.npmmirror.com`,然后再执行`pnpm install`。 +- 如果你不想使用`corepack`,你需要禁用`corepack`,然后使用你自己的`pnpm`进行安装。 ::: diff --git a/internal/vite-config/src/plugins/index.ts b/internal/vite-config/src/plugins/index.ts index 691d3224..da08db4b 100644 --- a/internal/vite-config/src/plugins/index.ts +++ b/internal/vite-config/src/plugins/index.ts @@ -243,4 +243,5 @@ export { viteDtsPlugin, viteHtmlPlugin, viteVisualizerPlugin, + viteVxeTableImportsPlugin, }; diff --git a/internal/vite-config/src/plugins/vxe-table.ts b/internal/vite-config/src/plugins/vxe-table.ts index 3c107a7f..8cd53504 100644 --- a/internal/vite-config/src/plugins/vxe-table.ts +++ b/internal/vite-config/src/plugins/vxe-table.ts @@ -4,6 +4,35 @@ import { lazyImport, VxeResolver } from 'vite-plugin-lazy-import'; async function viteVxeTableImportsPlugin(): Promise { return [ + // { + // config() { + // return { + // optimizeDeps: { + // include: [ + // 'vxe-pc-ui/es/vxe-button/index.js', + // 'vxe-pc-ui/es/vxe-checkbox/index.js', + // 'vxe-pc-ui/es/vxe-icon/index.js', + // 'vxe-pc-ui/es/vxe-input/index.js', + // 'vxe-pc-ui/es/vxe-loading/index.js', + // 'vxe-pc-ui/es/vxe-modal/index.js', + // 'vxe-pc-ui/es/vxe-pager/index.js', + // 'vxe-pc-ui/es/vxe-radio-group/index.js', + // 'vxe-pc-ui/es/vxe-select/index.js', + // 'vxe-pc-ui/es/vxe-tooltip/index.js', + // 'vxe-pc-ui/es/vxe-ui/index.js', + // 'vxe-pc-ui/es/vxe-upload/index.js', + // 'vxe-table/es/vxe-colgroup/index.js', + // 'vxe-table/es/vxe-column/index.js', + // 'vxe-table/es/vxe-grid/index.js', + // 'vxe-table/es/vxe-table/index.js', + // 'vxe-table/es/vxe-toolbar/index.js', + // 'vxe-table/es/vxe-ui/index.js', + // ], + // }, + // }; + // }, + // name: 'vxe-table-adapter', + // }, lazyImport({ resolvers: [ VxeResolver({ diff --git a/package.json b/package.json index 0b9b6e65..b8bb81f9 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ }, "engines": { "node": ">=20.10.0", - "pnpm": ">=9.5.0" + "pnpm": ">=9.12.0" }, "packageManager": "pnpm@9.12.3", "pnpm": { diff --git a/packages/effects/plugins/src/vxe-table/theme.css b/packages/effects/plugins/src/vxe-table/theme.css index a6e8ca1d..9ff9646d 100644 --- a/packages/effects/plugins/src/vxe-table/theme.css +++ b/packages/effects/plugins/src/vxe-table/theme.css @@ -1,4 +1,4 @@ -:root { +:root .vxe-grid { --vxe-ui-font-color: hsl(var(--foreground)); --vxe-ui-font-primary-color: hsl(var(--primary)); @@ -14,7 +14,7 @@ /* layout */ --vxe-ui-layout-background-color: hsl(var(--background)); - --vxe-ui-table-resizable-line-color: hsl(var(--border)); + --vxe-ui-table-resizable-line-color: hsl(var(--heavy)); /* --vxe-ui-table-fixed-left-scrolling-box-shadow: 8px 0px 10px -5px hsl(var(--accent)); --vxe-ui-table-fixed-right-scrolling-box-shadow: -8px 0px 10px -5px hsl(var(--accent)); */ @@ -66,15 +66,13 @@ box-shadow: 0 0 0 1px hsl(var(--border)); } - .vxe-pager { - &--wrapper { - display: flex; - align-items: center; - } + .vxe-pager--wrapper { + display: flex; + align-items: center; + } - &--sizes { - margin-right: auto; - } + .vxe-pager--sizes { + margin-right: auto; } } diff --git a/packages/effects/plugins/src/vxe-table/use-vxe-grid.ts b/packages/effects/plugins/src/vxe-table/use-vxe-grid.ts index f3321a4b..a309f5ac 100644 --- a/packages/effects/plugins/src/vxe-table/use-vxe-grid.ts +++ b/packages/effects/plugins/src/vxe-table/use-vxe-grid.ts @@ -41,3 +41,5 @@ export function useVbenVxeGrid(options: VxeGridProps) { return [Grid, extendedApi] as const; } + +export type UseVbenVxeGrid = typeof useVbenVxeGrid; diff --git a/playground/src/adapter/vxe-table.ts b/playground/src/adapter/vxe-table.ts index 8792d021..8f68b15d 100644 --- a/playground/src/adapter/vxe-table.ts +++ b/playground/src/adapter/vxe-table.ts @@ -39,7 +39,7 @@ setupVbenVxeTable({ // 表格配置项可以用 cellRender: { name: 'CellImage' }, vxeUI.renderer.add('CellImage', { - renderDefault(_renderOpts, params) { + renderTableDefault(_renderOpts, params) { const { column, row } = params; return h(Image, { src: row[column.field] }); }, @@ -47,7 +47,7 @@ setupVbenVxeTable({ // 表格配置项可以用 cellRender: { name: 'CellLink' }, vxeUI.renderer.add('CellLink', { - renderDefault(renderOpts) { + renderTableDefault(renderOpts) { const { props } = renderOpts; return h( Button, diff --git a/playground/src/bootstrap.ts b/playground/src/bootstrap.ts index b522068c..09b8cfa8 100644 --- a/playground/src/bootstrap.ts +++ b/playground/src/bootstrap.ts @@ -1,17 +1,19 @@ -import { createApp } from 'vue'; +import { createApp, watchEffect } from 'vue'; import { registerAccessDirective } from '@vben/access'; +import { preferences } from '@vben/preferences'; import { initStores } from '@vben/stores'; import '@vben/styles'; import '@vben/styles/antd'; import { VueQueryPlugin } from '@tanstack/vue-query'; +import { useTitle } from '@vueuse/core'; -import { setupI18n } from '#/locales'; +import { $t, setupI18n } from '#/locales'; +import { router } from '#/router'; import { initComponentAdapter } from './adapter/component'; import App from './app.vue'; -import { router } from './router'; async function bootstrap(namespace: string) { // 初始化组件适配器 @@ -34,6 +36,16 @@ async function bootstrap(namespace: string) { // 配置@tanstack/vue-query app.use(VueQueryPlugin); + // 动态更新标题 + watchEffect(() => { + if (preferences.app.dynamicTitle) { + const routeTitle = router.currentRoute.value.meta?.title; + const pageTitle = + (routeTitle ? `${$t(routeTitle)} - ` : '') + preferences.app.name; + useTitle(pageTitle); + } + }); + app.mount('#app'); } diff --git a/playground/src/preferences.ts b/playground/src/preferences.ts index 63edb3a9..b2e9ace4 100644 --- a/playground/src/preferences.ts +++ b/playground/src/preferences.ts @@ -3,6 +3,7 @@ import { defineOverridesPreferences } from '@vben/preferences'; /** * @description 项目配置文件 * 只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置 + * !!! 更改配置后请清空缓存,否则可能不生效 */ export const overridesPreferences = defineOverridesPreferences({ // overrides diff --git a/playground/src/router/guard.ts b/playground/src/router/guard.ts index ff7aa2bc..bddb28db 100644 --- a/playground/src/router/guard.ts +++ b/playground/src/router/guard.ts @@ -5,9 +5,6 @@ import { preferences } from '@vben/preferences'; import { useAccessStore, useUserStore } from '@vben/stores'; import { startProgress, stopProgress } from '@vben/utils'; -import { useTitle } from '@vueuse/core'; - -import { $t } from '#/locales'; import { accessRoutes, coreRouteNames } from '#/router/routes'; import { useAuthStore } from '#/store'; @@ -39,13 +36,6 @@ function setupCommonGuard(router: Router) { if (preferences.transition.progress) { stopProgress(); } - - // 动态修改标题 - if (preferences.app.dynamicTitle) { - const { title } = to.meta; - // useTitle(`${$t(title)} - ${preferences.app.name}`); - useTitle(`${$t(title)} - ${preferences.app.name}`); - } }); } diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c5eb0a57..3a566493 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -23,7 +23,7 @@ catalog: '@ctrl/tinycolor': ^4.1.0 '@eslint/js': ^9.14.0 '@faker-js/faker': ^9.2.0 - '@iconify/json': ^2.2.267 + '@iconify/json': ^2.2.268 '@iconify/tailwind': ^1.1.3 '@iconify/vue': ^4.1.2 '@intlify/core-base': ^10.0.4 @@ -44,13 +44,13 @@ catalog: '@types/jsonwebtoken': ^9.0.7 '@types/lodash.clonedeep': ^4.5.9 '@types/lodash.get': ^4.4.9 - '@types/node': ^22.8.7 + '@types/node': ^22.9.0 '@types/nprogress': ^0.2.3 '@types/postcss-import': ^14.0.3 '@types/qrcode': ^1.5.5 '@types/sortablejs': ^1.15.8 - '@typescript-eslint/eslint-plugin': ^8.12.2 - '@typescript-eslint/parser': ^8.12.2 + '@typescript-eslint/eslint-plugin': ^8.13.0 + '@typescript-eslint/parser': ^8.13.0 '@vee-validate/zod': ^4.14.6 '@vite-pwa/vitepress': ^0.5.3 '@vitejs/plugin-vue': ^5.1.4 @@ -71,7 +71,7 @@ catalog: circular-dependency-scanner: ^2.3.0 class-variance-authority: ^0.7.0 clsx: ^2.1.1 - commitlint-plugin-function-rules: ^4.0.0 + commitlint-plugin-function-rules: ^4.0.1 consola: ^3.2.3 cross-env: ^7.0.3 cspell: ^8.15.7 @@ -105,7 +105,7 @@ catalog: get-port: ^7.1.0 globals: ^15.12.0 h3: ^1.13.0 - happy-dom: ^15.8.3 + happy-dom: ^15.10.1 html-minifier-terser: ^7.2.0 husky: ^9.1.6 is-ci: ^3.0.1 @@ -117,7 +117,7 @@ catalog: lucide-vue-next: ^0.454.0 medium-zoom: ^1.1.0 naive-ui: ^2.40.1 - nitropack: ^2.10.2 + nitropack: ^2.10.3 nprogress: ^0.2.0 ora: ^8.1.1 pinia: 2.2.2 @@ -139,7 +139,7 @@ catalog: rimraf: ^6.0.1 rollup: ^4.24.4 rollup-plugin-visualizer: ^5.12.0 - sass: 1.79.5 + sass: 1.80.6 sortablejs: ^1.15.3 stylelint: ^16.10.0 stylelint-config-recess-order: ^5.1.1 @@ -165,8 +165,8 @@ catalog: vite-plugin-html: ^3.2.2 vite-plugin-lazy-import: ^1.0.7 vite-plugin-pwa: ^0.20.5 - vite-plugin-vue-devtools: ^7.6.2 - vitepress: ^1.4.5 + vite-plugin-vue-devtools: ^7.6.3 + vitepress: ^1.5.0 vitepress-plugin-group-icons: ^1.3.0 vitest: ^2.1.4 vue: ^3.5.12 @@ -174,8 +174,8 @@ catalog: vue-i18n: ^10.0.4 vue-router: ^4.4.5 vue-tsc: ^2.1.10 - vxe-pc-ui: ^4.2.40 - vxe-table: ^4.8.0 + vxe-pc-ui: ^4.2.42 + vxe-table: ^4.8.1 watermark-js-plus: ^1.5.7 zod: ^3.23.8 zod-defaults: ^0.1.3