diff --git a/apps/backend-mock/utils/mock-data.ts b/apps/backend-mock/utils/mock-data.ts index 057588e3..3967b906 100644 --- a/apps/backend-mock/utils/mock-data.ts +++ b/apps/backend-mock/utils/mock-data.ts @@ -53,7 +53,6 @@ export const MOCK_CODES = [ const dashboardMenus = [ { - component: 'BasicLayout', meta: { order: -1, title: 'page.dashboard.title', @@ -116,7 +115,6 @@ const createDemosMenus = (role: 'admin' | 'super' | 'user') => { return [ { - component: 'BasicLayout', meta: { icon: 'ic:baseline-view-in-ar', keepAlive: true, diff --git a/apps/web-antd/src/bootstrap.ts b/apps/web-antd/src/bootstrap.ts index 43b6f787..b2d106e8 100644 --- a/apps/web-antd/src/bootstrap.ts +++ b/apps/web-antd/src/bootstrap.ts @@ -20,6 +20,15 @@ async function bootstrap(namespace: string) { // 初始化组件适配器 await initComponentAdapter(); + // // 设置弹窗的默认配置 + // setDefaultModalProps({ + // fullscreenButton: false, + // }); + // // 设置抽屉的默认配置 + // setDefaultDrawerProps({ + // zIndex: 1020, + // }); + const app = createApp(App); // 全局组件 diff --git a/apps/web-antd/src/router/routes/core.ts b/apps/web-antd/src/router/routes/core.ts index cb84714b..4ecb68f8 100644 --- a/apps/web-antd/src/router/routes/core.ts +++ b/apps/web-antd/src/router/routes/core.ts @@ -2,7 +2,7 @@ import type { RouteRecordRaw } from 'vue-router'; import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants'; -import { AuthPageLayout } from '#/layouts'; +import { AuthPageLayout, BasicLayout } from '#/layouts'; import { $t } from '#/locales'; import Login from '#/views/_core/authentication/login.vue'; @@ -21,13 +21,21 @@ const fallbackNotFoundRoute: RouteRecordRaw = { /** 基本路由,这些路由是必须存在的 */ const coreRoutes: RouteRecordRaw[] = [ + /** + * 根路由 + * 使用基础布局,作为所有页面的父级容器,子级就不必配置BasicLayout。 + * 此路由必须存在,且不应修改 + */ { + component: BasicLayout, meta: { + hideInBreadcrumb: true, title: 'Root', }, name: 'Root', path: '/', redirect: DEFAULT_HOME_PATH, + children: [], }, { component: () => import('#/views/_core/social-callback/index.vue'), diff --git a/apps/web-antd/src/router/routes/modules/dashboard.ts b/apps/web-antd/src/router/routes/modules/dashboard.ts index 1bddab9d..f3a952b0 100644 --- a/apps/web-antd/src/router/routes/modules/dashboard.ts +++ b/apps/web-antd/src/router/routes/modules/dashboard.ts @@ -1,11 +1,9 @@ import type { RouteRecordRaw } from 'vue-router'; -import { BasicLayout } from '#/layouts'; import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ { - component: BasicLayout, meta: { icon: 'lucide:layout-dashboard', order: -1, diff --git a/apps/web-antd/src/router/routes/modules/demos.ts b/apps/web-antd/src/router/routes/modules/demos.ts index 32bb338e..55ade09c 100644 --- a/apps/web-antd/src/router/routes/modules/demos.ts +++ b/apps/web-antd/src/router/routes/modules/demos.ts @@ -1,11 +1,9 @@ import type { RouteRecordRaw } from 'vue-router'; -import { BasicLayout } from '#/layouts'; import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ { - component: BasicLayout, meta: { icon: 'ic:baseline-view-in-ar', keepAlive: true, diff --git a/apps/web-antd/src/router/routes/modules/vben.ts b/apps/web-antd/src/router/routes/modules/vben.ts index f1493889..a54bb8f8 100644 --- a/apps/web-antd/src/router/routes/modules/vben.ts +++ b/apps/web-antd/src/router/routes/modules/vben.ts @@ -8,16 +8,15 @@ import { VBEN_NAIVE_PREVIEW_URL, } from '@vben/constants'; -import { BasicLayout, IFrameView } from '#/layouts'; +import { IFrameView } from '#/layouts'; import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ { - component: BasicLayout, meta: { badgeType: 'dot', icon: VBEN_LOGO_URL, - order: 9999, + order: 9998, title: $t('demos.vben.title'), }, name: 'VbenProject', @@ -76,6 +75,16 @@ const routes: RouteRecordRaw[] = [ }, ], }, + { + name: 'VbenAbout', + path: '/vben-admin/about', + component: () => import('#/views/_core/about/index.vue'), + meta: { + icon: 'lucide:copyright', + title: $t('demos.vben.about'), + order: 9999, + }, + }, ]; export default routes; diff --git a/apps/web-ele/src/bootstrap.ts b/apps/web-ele/src/bootstrap.ts index 9cdb0863..b62094f2 100644 --- a/apps/web-ele/src/bootstrap.ts +++ b/apps/web-ele/src/bootstrap.ts @@ -19,6 +19,14 @@ import { router } from './router'; async function bootstrap(namespace: string) { // 初始化组件适配器 await initComponentAdapter(); + // // 设置弹窗的默认配置 + // setDefaultModalProps({ + // fullscreenButton: false, + // }); + // // 设置抽屉的默认配置 + // setDefaultDrawerProps({ + // zIndex: 2000, + // }); const app = createApp(App); // 注册Element Plus提供的v-loading指令 diff --git a/apps/web-ele/src/router/routes/core.ts b/apps/web-ele/src/router/routes/core.ts index fe030a9a..7218da22 100644 --- a/apps/web-ele/src/router/routes/core.ts +++ b/apps/web-ele/src/router/routes/core.ts @@ -2,7 +2,7 @@ import type { RouteRecordRaw } from 'vue-router'; import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants'; -import { AuthPageLayout } from '#/layouts'; +import { AuthPageLayout, BasicLayout } from '#/layouts'; import { $t } from '#/locales'; import Login from '#/views/_core/authentication/login.vue'; @@ -21,13 +21,21 @@ const fallbackNotFoundRoute: RouteRecordRaw = { /** 基本路由,这些路由是必须存在的 */ const coreRoutes: RouteRecordRaw[] = [ + /** + * 根路由 + * 使用基础布局,作为所有页面的父级容器,子级就不必配置BasicLayout。 + * 此路由必须存在,且不应修改 + */ { + component: BasicLayout, meta: { + hideInBreadcrumb: true, title: 'Root', }, name: 'Root', path: '/', redirect: DEFAULT_HOME_PATH, + children: [], }, { component: AuthPageLayout, diff --git a/apps/web-ele/src/router/routes/modules/dashboard.ts b/apps/web-ele/src/router/routes/modules/dashboard.ts index 1bddab9d..f3a952b0 100644 --- a/apps/web-ele/src/router/routes/modules/dashboard.ts +++ b/apps/web-ele/src/router/routes/modules/dashboard.ts @@ -1,11 +1,9 @@ import type { RouteRecordRaw } from 'vue-router'; -import { BasicLayout } from '#/layouts'; import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ { - component: BasicLayout, meta: { icon: 'lucide:layout-dashboard', order: -1, diff --git a/apps/web-ele/src/router/routes/modules/demos.ts b/apps/web-ele/src/router/routes/modules/demos.ts index 90cc2f11..907ea3f4 100644 --- a/apps/web-ele/src/router/routes/modules/demos.ts +++ b/apps/web-ele/src/router/routes/modules/demos.ts @@ -1,11 +1,9 @@ import type { RouteRecordRaw } from 'vue-router'; -import { BasicLayout } from '#/layouts'; import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ { - component: BasicLayout, meta: { icon: 'ic:baseline-view-in-ar', keepAlive: true, diff --git a/apps/web-ele/src/router/routes/modules/vben.ts b/apps/web-ele/src/router/routes/modules/vben.ts index 2cfef549..20fbc96c 100644 --- a/apps/web-ele/src/router/routes/modules/vben.ts +++ b/apps/web-ele/src/router/routes/modules/vben.ts @@ -9,30 +9,20 @@ import { } from '@vben/constants'; import { SvgAntdvLogoIcon } from '@vben/icons'; -import { BasicLayout, IFrameView } from '#/layouts'; +import { IFrameView } from '#/layouts'; import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ { - component: BasicLayout, meta: { badgeType: 'dot', icon: VBEN_LOGO_URL, - order: 9999, + order: 9998, title: $t('demos.vben.title'), }, name: 'VbenProject', path: '/vben-admin', children: [ - { - name: 'VbenAbout', - path: '/vben-admin/about', - component: () => import('#/views/_core/about/index.vue'), - meta: { - icon: 'lucide:copyright', - title: $t('demos.vben.about'), - }, - }, { name: 'VbenDocument', path: '/vben-admin/document', @@ -77,6 +67,16 @@ const routes: RouteRecordRaw[] = [ }, ], }, + { + name: 'VbenAbout', + path: '/vben-admin/about', + component: () => import('#/views/_core/about/index.vue'), + meta: { + icon: 'lucide:copyright', + title: $t('demos.vben.about'), + order: 9999, + }, + }, ]; export default routes; diff --git a/apps/web-naive/src/bootstrap.ts b/apps/web-naive/src/bootstrap.ts index d4172b28..a423bff4 100644 --- a/apps/web-naive/src/bootstrap.ts +++ b/apps/web-naive/src/bootstrap.ts @@ -18,6 +18,16 @@ import { router } from './router'; async function bootstrap(namespace: string) { // 初始化组件适配器 initComponentAdapter(); + + // // 设置弹窗的默认配置 + // setDefaultModalProps({ + // fullscreenButton: false, + // }); + // // 设置抽屉的默认配置 + // setDefaultDrawerProps({ + // // zIndex: 2000, + // }); + const app = createApp(App); // 国际化 i18n 配置 diff --git a/apps/web-naive/src/router/routes/core.ts b/apps/web-naive/src/router/routes/core.ts index fe030a9a..7218da22 100644 --- a/apps/web-naive/src/router/routes/core.ts +++ b/apps/web-naive/src/router/routes/core.ts @@ -2,7 +2,7 @@ import type { RouteRecordRaw } from 'vue-router'; import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants'; -import { AuthPageLayout } from '#/layouts'; +import { AuthPageLayout, BasicLayout } from '#/layouts'; import { $t } from '#/locales'; import Login from '#/views/_core/authentication/login.vue'; @@ -21,13 +21,21 @@ const fallbackNotFoundRoute: RouteRecordRaw = { /** 基本路由,这些路由是必须存在的 */ const coreRoutes: RouteRecordRaw[] = [ + /** + * 根路由 + * 使用基础布局,作为所有页面的父级容器,子级就不必配置BasicLayout。 + * 此路由必须存在,且不应修改 + */ { + component: BasicLayout, meta: { + hideInBreadcrumb: true, title: 'Root', }, name: 'Root', path: '/', redirect: DEFAULT_HOME_PATH, + children: [], }, { component: AuthPageLayout, diff --git a/apps/web-naive/src/router/routes/modules/dashboard.ts b/apps/web-naive/src/router/routes/modules/dashboard.ts index 1bddab9d..f3a952b0 100644 --- a/apps/web-naive/src/router/routes/modules/dashboard.ts +++ b/apps/web-naive/src/router/routes/modules/dashboard.ts @@ -1,11 +1,9 @@ import type { RouteRecordRaw } from 'vue-router'; -import { BasicLayout } from '#/layouts'; import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ { - component: BasicLayout, meta: { icon: 'lucide:layout-dashboard', order: -1, diff --git a/apps/web-naive/src/router/routes/modules/demos.ts b/apps/web-naive/src/router/routes/modules/demos.ts index d0631cb5..5e49ffa0 100644 --- a/apps/web-naive/src/router/routes/modules/demos.ts +++ b/apps/web-naive/src/router/routes/modules/demos.ts @@ -1,11 +1,9 @@ import type { RouteRecordRaw } from 'vue-router'; -import { BasicLayout } from '#/layouts'; import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ { - component: BasicLayout, meta: { icon: 'ic:baseline-view-in-ar', keepAlive: true, diff --git a/apps/web-naive/src/router/routes/modules/vben.ts b/apps/web-naive/src/router/routes/modules/vben.ts index 44461a7f..169de855 100644 --- a/apps/web-naive/src/router/routes/modules/vben.ts +++ b/apps/web-naive/src/router/routes/modules/vben.ts @@ -9,30 +9,20 @@ import { } from '@vben/constants'; import { SvgAntdvLogoIcon } from '@vben/icons'; -import { BasicLayout, IFrameView } from '#/layouts'; +import { IFrameView } from '#/layouts'; import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ { - component: BasicLayout, meta: { badgeType: 'dot', icon: VBEN_LOGO_URL, - order: 9999, + order: 9998, title: $t('demos.vben.title'), }, name: 'VbenProject', path: '/vben-admin', children: [ - { - name: 'VbenAbout', - path: '/vben-admin/about', - component: () => import('#/views/_core/about/index.vue'), - meta: { - icon: 'lucide:copyright', - title: $t('demos.vben.about'), - }, - }, { name: 'VbenDocument', path: '/vben-admin/document', @@ -77,6 +67,16 @@ const routes: RouteRecordRaw[] = [ }, ], }, + { + name: 'VbenAbout', + path: '/vben-admin/about', + component: () => import('#/views/_core/about/index.vue'), + meta: { + icon: 'lucide:copyright', + title: $t('demos.vben.about'), + order: 9999, + }, + }, ]; export default routes; diff --git a/docs/src/components/common-ui/vben-drawer.md b/docs/src/components/common-ui/vben-drawer.md index 04420855..61b7c9e5 100644 --- a/docs/src/components/common-ui/vben-drawer.md +++ b/docs/src/components/common-ui/vben-drawer.md @@ -55,6 +55,7 @@ Drawer 内的内容一般业务中,会比较复杂,所以我们可以将 dra - `VbenDrawer` 组件对与参数的处理优先级是 `slot` > `props` > `state`(通过api更新的状态以及useVbenDrawer参数)。如果你已经传入了 `slot` 或者 `props`,那么 `setState` 将不会生效,这种情况下你可以通过 `slot` 或者 `props` 来更新状态。 - 如果你使用到了 `connectedComponent` 参数,那么会存在 2 个`useVbenDrawer`, 此时,如果同时设置了相同的参数,那么以内部为准(也就是没有设置 connectedComponent 的代码)。比如 同时设置了 `onConfirm`,那么以内部的 `onConfirm` 为准。`onOpenChange`事件除外,内外都会触发。 - 使用了`connectedComponent`参数时,可以配置`destroyOnClose`属性来决定当关闭弹窗时,是否要销毁`connectedComponent`组件(重新创建`connectedComponent`组件,这将会把其内部所有的变量、状态、数据等恢复到初始状态。)。 +- 如果抽屉的默认行为不符合你的预期,可以在`src\bootstrap.ts`中修改`setDefaultDrawerProps`的参数来设置默认的属性,如默认隐藏全屏按钮,修改默认ZIndex等。 ::: diff --git a/docs/src/components/common-ui/vben-form.md b/docs/src/components/common-ui/vben-form.md index a15c366f..0193e070 100644 --- a/docs/src/components/common-ui/vben-form.md +++ b/docs/src/components/common-ui/vben-form.md @@ -316,7 +316,7 @@ useVbenForm 返回的第二个参数,是一个对象,包含了一些表单 | collapsed | 是否折叠,在`showCollapseButton`为`true`时生效 | `boolean` | `false` | | collapseTriggerResize | 折叠时,触发`resize`事件 | `boolean` | `false` | | collapsedRows | 折叠时保持的行数 | `number` | `1` | -| fieldMappingTime | 用于将表单内的数组值值映射成 2 个字段 | `[string, [string, string],Nullable?][]` | - | +| fieldMappingTime | 用于将表单内的数组值值映射成 2 个字段 | `[string, [string, string],Nullable\|[string,string]\|((any,string)=>any)?][]` | - | | commonConfig | 表单项的通用配置,每个配置都会传递到每个表单项,表单项可覆盖 | `FormCommonConfig` | - | | schema | 表单项的每一项配置 | `FormSchema[]` | - | | submitOnEnter | 按下回车健时提交表单 | `boolean` | false | @@ -324,7 +324,7 @@ useVbenForm 返回的第二个参数,是一个对象,包含了一些表单 ::: tip fieldMappingTime -此属性用于将表单内的数组值映射成 2 个字段,例如:`[['timeRange', ['startTime', 'endTime'], 'YYYY-MM-DD']]`,`timeRange`应当是一个至少具有2个成员的数组类型的值。Form会将`timeRange`的值前两个值分别按照格式掩码`YYYY-MM-DD`格式化后映射到`startTime`和`endTime`字段上。如果明确地将格式掩码设为null,则原值映射而不进行格式化(适用于非日期时间字段)。 +此属性用于将表单内的数组值映射成 2 个字段,它应当传入一个数组,数组的每一项是一个映射规则,规则的第一个成员是一个字符串,表示需要映射的字段名,第二个成员是一个数组,表示映射后的字段名,第三个成员是一个可选的格式掩码,用于格式化日期时间字段;也可以提供一个格式化函数(参数分别为当前值和当前字段名,返回格式化后的值)。如果明确地将格式掩码设为null,则原值映射而不进行格式化(适用于非日期时间字段)。例如:`[['timeRange', ['startTime', 'endTime'], 'YYYY-MM-DD']]`,`timeRange`应当是一个至少具有2个成员的数组类型的值。Form会将`timeRange`的值前两个值分别按照格式掩码`YYYY-MM-DD`格式化后映射到`startTime`和`endTime`字段上。每一项的第三个参数是一个可选的格式掩码, ::: diff --git a/docs/src/components/common-ui/vben-modal.md b/docs/src/components/common-ui/vben-modal.md index f3e2a17b..8d0b4284 100644 --- a/docs/src/components/common-ui/vben-modal.md +++ b/docs/src/components/common-ui/vben-modal.md @@ -61,6 +61,7 @@ Modal 内的内容一般业务中,会比较复杂,所以我们可以将 moda - `VbenModal` 组件对与参数的处理优先级是 `slot` > `props` > `state`(通过api更新的状态以及useVbenModal参数)。如果你已经传入了 `slot` 或者 `props`,那么 `setState` 将不会生效,这种情况下你可以通过 `slot` 或者 `props` 来更新状态。 - 如果你使用到了 `connectedComponent` 参数,那么会存在 2 个`useVbenModal`, 此时,如果同时设置了相同的参数,那么以内部为准(也就是没有设置 connectedComponent 的代码)。比如 同时设置了 `onConfirm`,那么以内部的 `onConfirm` 为准。`onOpenChange`事件除外,内外都会触发。 - 使用了`connectedComponent`参数时,可以配置`destroyOnClose`属性来决定当关闭弹窗时,是否要销毁`connectedComponent`组件(重新创建`connectedComponent`组件,这将会把其内部所有的变量、状态、数据等恢复到初始状态。)。 +- 如果弹窗的默认行为不符合你的预期,可以在`src\bootstrap.ts`中修改`setDefaultModalProps`的参数来设置默认的属性,如默认隐藏全屏按钮,修改默认ZIndex等。 ::: diff --git a/docs/src/en/guide/essentials/route.md b/docs/src/en/guide/essentials/route.md index bef40d69..8fb0a6d1 100644 --- a/docs/src/en/guide/essentials/route.md +++ b/docs/src/en/guide/essentials/route.md @@ -73,7 +73,6 @@ import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ { - component: BasicLayout, meta: { badgeType: 'dot', badgeVariants: 'destructive', @@ -124,7 +123,6 @@ import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ { - component: BasicLayout, meta: { icon: 'ic:baseline-view-in-ar', keepAlive: true, @@ -249,7 +247,6 @@ import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ { - component: BasicLayout, meta: { icon: 'mdi:home', title: $t('page.home.title'), diff --git a/docs/src/guide/essentials/route.md b/docs/src/guide/essentials/route.md index 0eb74aea..d8a938dd 100644 --- a/docs/src/guide/essentials/route.md +++ b/docs/src/guide/essentials/route.md @@ -62,12 +62,10 @@ import type { RouteRecordRaw } from 'vue-router'; import { VBEN_LOGO_URL } from '@vben/constants'; -import { BasicLayout } from '#/layouts'; import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ { - component: BasicLayout, meta: { badgeType: 'dot', badgeVariants: 'destructive', @@ -103,7 +101,6 @@ export default routes; ::: tip -- 多级路由的父级路由无需设置 `component` 属性,只需设置 `children` 属性即可。除非你真的需要在父级路由嵌套下显示内容。 - 如果没有特殊情况,父级路由的 `redirect` 属性,不需要指定,默认会指向第一个子路由。 ::: @@ -113,12 +110,10 @@ export default routes; ```ts import type { RouteRecordRaw } from 'vue-router'; -import { BasicLayout } from '#/layouts'; import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ { - component: BasicLayout, meta: { icon: 'ic:baseline-view-in-ar', keepAlive: true, @@ -238,12 +233,10 @@ import type { RouteRecordRaw } from 'vue-router'; import { VBEN_LOGO_URL } from '@vben/constants'; -import { BasicLayout } from '#/layouts'; import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ { - component: BasicLayout, meta: { icon: 'mdi:home', title: $t('page.home.title'), @@ -400,6 +393,10 @@ interface RouteMeta { * 菜单可以看到,但是访问会被重定向到403 */ menuVisibleWithForbidden?: boolean; + /** + * 当前路由不使用基础布局(仅在顶级生效) + */ + noBasicLayout?: boolean; /** * 在新窗口打开 */ @@ -584,6 +581,13 @@ _注意:_ 排序仅针对一级菜单有效,二级菜单的排序需要在对 用于配置页面的菜单参数,会在菜单中传递给页面。 +### noBasicLayout + +- 类型:`boolean` +- 默认值:`false` + +用于配置当前路由不使用基础布局,仅在顶级时生效。默认情况下,所有的路由都会被包裹在基础布局中(包含顶部以及侧边等导航部件),如果你的页面不需要这些部件,可以设置 `noBasicLayout` 为 `true`。 + ## 路由刷新 路由刷新方式如下: diff --git a/packages/@core/base/design/src/css/ui.css b/packages/@core/base/design/src/css/ui.css index 3a002f2a..f7119c8b 100644 --- a/packages/@core/base/design/src/css/ui.css +++ b/packages/@core/base/design/src/css/ui.css @@ -81,3 +81,7 @@ transform: translateY(0); } } + +.z-popup { + z-index: var(--popup-z-index); +} diff --git a/packages/@core/base/design/src/design-tokens/default.css b/packages/@core/base/design/src/design-tokens/default.css index c81ace7e..6fb71f17 100644 --- a/packages/@core/base/design/src/design-tokens/default.css +++ b/packages/@core/base/design/src/design-tokens/default.css @@ -1,4 +1,6 @@ :root { + /** 弹出层的基础层级 **/ + --popup-z-index: 2000; --font-family: -apple-system, blinkmacsystemfont, 'Segoe UI', roboto, 'Helvetica Neue', arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; diff --git a/packages/@core/base/typings/src/vue-router.d.ts b/packages/@core/base/typings/src/vue-router.d.ts index 92736c91..099e8171 100644 --- a/packages/@core/base/typings/src/vue-router.d.ts +++ b/packages/@core/base/typings/src/vue-router.d.ts @@ -97,6 +97,10 @@ interface RouteMeta { * 菜单可以看到,但是访问会被重定向到403 */ menuVisibleWithForbidden?: boolean; + /** + * 不使用基础布局(仅在顶级生效) + */ + noBasicLayout?: boolean; /** * 在新窗口打开 */ @@ -116,10 +120,13 @@ interface RouteMeta { } // 定义递归类型以将 RouteRecordRaw 的 component 属性更改为 string -type RouteRecordStringComponent = { +type RouteRecordStringComponent = Omit< + RouteRecordRaw, + 'children' | 'component' +> & { children?: RouteRecordStringComponent[]; component: T; -} & Omit; +}; type ComponentRecordType = Record Promise>; diff --git a/packages/@core/ui-kit/form-ui/src/form-api.ts b/packages/@core/ui-kit/form-ui/src/form-api.ts index a2877cbf..2d1e971a 100644 --- a/packages/@core/ui-kit/form-ui/src/form-api.ts +++ b/packages/@core/ui-kit/form-ui/src/form-api.ts @@ -371,6 +371,9 @@ export class FormApi { if (format === null) { values[startTimeKey] = startTime; values[endTimeKey] = endTime; + } else if (isFunction(format)) { + values[startTimeKey] = format(startTime, startTimeKey); + values[endTimeKey] = format(endTime, endTimeKey); } else { const [startTimeFormat, endTimeFormat] = Array.isArray(format) ? format diff --git a/packages/@core/ui-kit/form-ui/src/types.ts b/packages/@core/ui-kit/form-ui/src/types.ts index 07a2afd4..dd007292 100644 --- a/packages/@core/ui-kit/form-ui/src/types.ts +++ b/packages/@core/ui-kit/form-ui/src/types.ts @@ -4,7 +4,7 @@ import type { ZodTypeAny } from 'zod'; import type { Component, HtmlHTMLAttributes, Ref } from 'vue'; import type { VbenButtonProps } from '@vben-core/shadcn-ui'; -import type { ClassType, MaybeComputedRef, Nullable } from '@vben-core/typings'; +import type { ClassType, MaybeComputedRef } from '@vben-core/typings'; import type { FormApi } from './form-api'; @@ -224,7 +224,12 @@ export type HandleResetFn = ( export type FieldMappingTime = [ string, [string, string], - ([string, string] | Nullable)?, + ( + | ((value: any, fieldName: string) => any) + | [string, string] + | null + | string + )?, ][]; export interface FormSchema< diff --git a/packages/@core/ui-kit/popup-ui/src/drawer/index.ts b/packages/@core/ui-kit/popup-ui/src/drawer/index.ts index f2dd8396..00f87b2c 100644 --- a/packages/@core/ui-kit/popup-ui/src/drawer/index.ts +++ b/packages/@core/ui-kit/popup-ui/src/drawer/index.ts @@ -1,3 +1,3 @@ export type * from './drawer'; export { default as VbenDrawer } from './drawer.vue'; -export { useVbenDrawer } from './use-drawer'; +export { setDefaultDrawerProps, useVbenDrawer } from './use-drawer'; diff --git a/packages/@core/ui-kit/popup-ui/src/drawer/use-drawer.ts b/packages/@core/ui-kit/popup-ui/src/drawer/use-drawer.ts index 7431509d..21b11c56 100644 --- a/packages/@core/ui-kit/popup-ui/src/drawer/use-drawer.ts +++ b/packages/@core/ui-kit/popup-ui/src/drawer/use-drawer.ts @@ -4,7 +4,6 @@ import type { ExtendedDrawerApi, } from './drawer'; -import { useStore } from '@vben-core/shared/store'; import { defineComponent, h, @@ -15,11 +14,19 @@ import { ref, } from 'vue'; -import VbenDrawer from './drawer.vue'; +import { useStore } from '@vben-core/shared/store'; + import { DrawerApi } from './drawer-api'; +import VbenDrawer from './drawer.vue'; const USER_DRAWER_INJECT_KEY = Symbol('VBEN_DRAWER_INJECT'); +const DEFAULT_DRAWER_PROPS: Partial = {}; + +export function setDefaultDrawerProps(props: Partial) { + Object.assign(DEFAULT_DRAWER_PROPS, props); +} + export function useVbenDrawer< TParentDrawerProps extends DrawerProps = DrawerProps, >(options: DrawerApiOptions = {}) { @@ -68,6 +75,7 @@ export function useVbenDrawer< const injectData = inject(USER_DRAWER_INJECT_KEY, {}); const mergedOptions = { + ...DEFAULT_DRAWER_PROPS, ...injectData.options, ...options, } as DrawerApiOptions; diff --git a/packages/@core/ui-kit/popup-ui/src/modal/index.ts b/packages/@core/ui-kit/popup-ui/src/modal/index.ts index c8d3498c..0cdedf2f 100644 --- a/packages/@core/ui-kit/popup-ui/src/modal/index.ts +++ b/packages/@core/ui-kit/popup-ui/src/modal/index.ts @@ -1,3 +1,3 @@ export type * from './modal'; export { default as VbenModal } from './modal.vue'; -export { useVbenModal } from './use-modal'; +export { setDefaultModalProps, useVbenModal } from './use-modal'; diff --git a/packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts b/packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts index 4a94c1f8..6cc0a30d 100644 --- a/packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts +++ b/packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts @@ -1,6 +1,5 @@ import type { ExtendedModalApi, ModalApiOptions, ModalProps } from './modal'; -import { useStore } from '@vben-core/shared/store'; import { defineComponent, h, @@ -11,11 +10,19 @@ import { ref, } from 'vue'; -import VbenModal from './modal.vue'; +import { useStore } from '@vben-core/shared/store'; + import { ModalApi } from './modal-api'; +import VbenModal from './modal.vue'; const USER_MODAL_INJECT_KEY = Symbol('VBEN_MODAL_INJECT'); +const DEFAULT_MODAL_PROPS: Partial = {}; + +export function setDefaultModalProps(props: Partial) { + Object.assign(DEFAULT_MODAL_PROPS, props); +} + export function useVbenModal( options: ModalApiOptions = {}, ) { @@ -67,6 +74,7 @@ export function useVbenModal( const injectData = inject(USER_MODAL_INJECT_KEY, {}); const mergedOptions = { + ...DEFAULT_MODAL_PROPS, ...injectData.options, ...options, } as ModalApiOptions; diff --git a/packages/@core/ui-kit/shadcn-ui/src/components/back-top/back-top.vue b/packages/@core/ui-kit/shadcn-ui/src/components/back-top/back-top.vue index 115b5b3a..1f8b0bc7 100644 --- a/packages/@core/ui-kit/shadcn-ui/src/components/back-top/back-top.vue +++ b/packages/@core/ui-kit/shadcn-ui/src/components/back-top/back-top.vue @@ -32,7 +32,7 @@ const { handleClick, visible } = useBackTop(props); -import type { ClassType } from '@vben-core/typings'; import type { ContextMenuContentProps, ContextMenuRootEmits, ContextMenuRootProps, } from 'radix-vue'; +import type { ClassType } from '@vben-core/typings'; + import type { IContextMenuItem } from './interface'; -import { useForwardPropsEmits } from 'radix-vue'; import { computed } from 'vue'; +import { useForwardPropsEmits } from 'radix-vue'; + import { ContextMenu, ContextMenuContent, @@ -21,14 +23,14 @@ import { } from '../../ui/context-menu'; const props = defineProps< - { + ContextMenuRootProps & { class?: ClassType; contentClass?: ClassType; contentProps?: ContextMenuContentProps; handlerData?: Record; itemClass?: ClassType; menus: (data: any) => IContextMenuItem[]; - } & ContextMenuRootProps + } >(); const emits = defineEmits(); @@ -67,7 +69,7 @@ function handleClick(menu: IContextMenuItem) {