mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-25 16:16:20 +08:00
Compare commits
51 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
195ceec9b4 | ||
![]() |
5bd73867b6 | ||
![]() |
22e6f28464 | ||
![]() |
5611f6c7f5 | ||
![]() |
3f0f4d50a1 | ||
![]() |
2d0859a727 | ||
![]() |
509b268fba | ||
![]() |
c3129663eb | ||
![]() |
816d1f5a69 | ||
![]() |
8cc903c0e1 | ||
![]() |
13087a10b7 | ||
![]() |
27a3888e35 | ||
![]() |
fb0ec05ff8 | ||
![]() |
76c4aa2c55 | ||
![]() |
e1c503e51e | ||
![]() |
5965755caa | ||
![]() |
1ad54561b0 | ||
![]() |
42e322012c | ||
![]() |
8cf6e8ec75 | ||
![]() |
79d4d2fb22 | ||
![]() |
b785bc5704 | ||
![]() |
6719e2679f | ||
![]() |
cb9c8db5ba | ||
![]() |
a2637313f8 | ||
![]() |
467689525f | ||
![]() |
1a04a05b79 | ||
![]() |
b8bffd884c | ||
![]() |
624beb6fa0 | ||
![]() |
7606b86854 | ||
![]() |
e10cbe23b9 | ||
![]() |
d34838bdd8 | ||
![]() |
c979c23e6b | ||
![]() |
516d0b8dc8 | ||
![]() |
99c7fd72f8 | ||
![]() |
2828e7a7b6 | ||
![]() |
16162c01ed | ||
![]() |
bbbdbfa912 | ||
![]() |
06cccc53fa | ||
![]() |
801c640724 | ||
![]() |
081d2aed23 | ||
![]() |
4d81b9d18d | ||
![]() |
e9dc613548 | ||
![]() |
3af22f7e91 | ||
![]() |
2135cb8ece | ||
![]() |
376aad5d26 | ||
![]() |
27ba45aa75 | ||
![]() |
de17007788 | ||
![]() |
e86a7906fe | ||
![]() |
4a8e6abc06 | ||
![]() |
2eb7fed9f4 | ||
![]() |
ff8d5ca351 |
17
.github/workflows/deploy.yml
vendored
17
.github/workflows/deploy.yml
vendored
@@ -153,3 +153,20 @@ jobs:
|
||||
username: ${{ secrets.WEB_NAIVE_FTP_ACCOUNT }}
|
||||
password: ${{ secrets.WEB_NAIVE_FTP_PASSWORD }}
|
||||
local-dir: ./apps/web-naive/dist/
|
||||
|
||||
rerun-on-failure:
|
||||
name: Rerun on failure
|
||||
needs:
|
||||
- deploy-playground-ftp
|
||||
- deploy-docs-ftp
|
||||
- deploy-antd-ftp
|
||||
- deploy-ele-ftp
|
||||
- deploy-naive-ftp
|
||||
if: failure() && fromJSON(github.run_attempt) < 10
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Retry ${{ fromJSON(github.run_attempt) }} of 10
|
||||
env:
|
||||
GH_REPO: ${{ github.repository }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: gh workflow run rerun.yml -F run_id=${{ github.run_id }}
|
||||
|
19
.github/workflows/rerun.yml
vendored
Normal file
19
.github/workflows/rerun.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: Rerun workflow
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
run_id:
|
||||
description: The workflow id to relanch
|
||||
required: true
|
||||
jobs:
|
||||
rerun:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: rerun ${{ inputs.run_id }}
|
||||
env:
|
||||
GH_REPO: ${{ github.repository }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
gh run watch ${{ inputs.run_id }} > /dev/null 2>&1
|
||||
gh run rerun ${{ inputs.run_id }} --failed
|
@@ -1,4 +1,10 @@
|
||||
export default {
|
||||
'*.md': ['prettier --cache --ignore-unknown --write'],
|
||||
'*.vue': [
|
||||
'prettier --write',
|
||||
'eslint --cache --fix',
|
||||
'stylelint --fix --allow-empty-input',
|
||||
],
|
||||
'*.{js,jsx,ts,tsx}': [
|
||||
'prettier --cache --ignore-unknown --write',
|
||||
'eslint --cache --fix',
|
||||
@@ -7,14 +13,8 @@ export default {
|
||||
'prettier --cache --ignore-unknown --write',
|
||||
'stylelint --fix --allow-empty-input',
|
||||
],
|
||||
'*.md': ['prettier --cache --ignore-unknown --write'],
|
||||
'*.vue': [
|
||||
'prettier --write',
|
||||
'eslint --cache --fix',
|
||||
'stylelint --fix --allow-empty-input',
|
||||
],
|
||||
'package.json': ['prettier --cache --write'],
|
||||
'{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': [
|
||||
'prettier --cache --write--parser json',
|
||||
],
|
||||
'package.json': ['prettier --cache --write'],
|
||||
};
|
||||
|
@@ -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,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/web-antd",
|
||||
"version": "5.5.2",
|
||||
"version": "5.5.3",
|
||||
"homepage": "https://vben.pro",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -3,9 +3,10 @@
|
||||
* 可用于 vben-form、vben-modal、vben-drawer 等组件使用,
|
||||
*/
|
||||
|
||||
import type { Component, SetupContext } from 'vue';
|
||||
|
||||
import type { BaseFormComponentType } from '@vben/common-ui';
|
||||
|
||||
import type { Component, SetupContext } from 'vue';
|
||||
import { h } from 'vue';
|
||||
|
||||
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
||||
|
@@ -1,12 +1,13 @@
|
||||
/**
|
||||
* 该文件可自行根据业务逻辑进行调整
|
||||
*/
|
||||
import type { HttpResponse } from '@vben/request';
|
||||
import type { RequestClientOptions } from '@vben/request';
|
||||
|
||||
import { useAppConfig } from '@vben/hooks';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import {
|
||||
authenticateResponseInterceptor,
|
||||
defaultResponseInterceptor,
|
||||
errorMessageResponseInterceptor,
|
||||
RequestClient,
|
||||
} from '@vben/request';
|
||||
@@ -20,8 +21,9 @@ import { refreshTokenApi } from './core';
|
||||
|
||||
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
||||
|
||||
function createRequestClient(baseURL: string) {
|
||||
function createRequestClient(baseURL: string, options?: RequestClientOptions) {
|
||||
const client = new RequestClient({
|
||||
...options,
|
||||
baseURL,
|
||||
});
|
||||
|
||||
@@ -69,19 +71,14 @@ function createRequestClient(baseURL: string) {
|
||||
},
|
||||
});
|
||||
|
||||
// response数据解构
|
||||
client.addResponseInterceptor<HttpResponse>({
|
||||
fulfilled: (response) => {
|
||||
const { data: responseData, status } = response;
|
||||
|
||||
const { code, data } = responseData;
|
||||
if (status >= 200 && status < 400 && code === 0) {
|
||||
return data;
|
||||
}
|
||||
|
||||
throw Object.assign({}, response, { response });
|
||||
},
|
||||
});
|
||||
// 处理返回的响应数据格式
|
||||
client.addResponseInterceptor(
|
||||
defaultResponseInterceptor({
|
||||
codeField: 'code',
|
||||
dataField: 'data',
|
||||
successCode: 0,
|
||||
}),
|
||||
);
|
||||
|
||||
// token过期的处理
|
||||
client.addResponseInterceptor(
|
||||
@@ -109,6 +106,8 @@ function createRequestClient(baseURL: string) {
|
||||
return client;
|
||||
}
|
||||
|
||||
export const requestClient = createRequestClient(apiURL);
|
||||
export const requestClient = createRequestClient(apiURL, {
|
||||
responseReturn: 'data',
|
||||
});
|
||||
|
||||
export const baseRequestClient = new RequestClient({ baseURL: apiURL });
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { createApp, watchEffect } from 'vue';
|
||||
|
||||
import { registerAccessDirective } from '@vben/access';
|
||||
import { initTippy } from '@vben/common-ui';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { initStores } from '@vben/stores';
|
||||
import '@vben/styles';
|
||||
@@ -18,6 +19,15 @@ async function bootstrap(namespace: string) {
|
||||
// 初始化组件适配器
|
||||
await initComponentAdapter();
|
||||
|
||||
// // 设置弹窗的默认配置
|
||||
// setDefaultModalProps({
|
||||
// fullscreenButton: false,
|
||||
// });
|
||||
// // 设置抽屉的默认配置
|
||||
// setDefaultDrawerProps({
|
||||
// zIndex: 1020,
|
||||
// });
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
// 国际化 i18n 配置
|
||||
@@ -29,6 +39,9 @@ async function bootstrap(namespace: string) {
|
||||
// 安装权限指令
|
||||
registerAccessDirective(app);
|
||||
|
||||
// 初始化 tippy
|
||||
initTippy(app);
|
||||
|
||||
// 配置路由及路由守卫
|
||||
app.use(router);
|
||||
|
||||
|
@@ -1,7 +1,9 @@
|
||||
import type { LocaleSetupOptions, SupportedLanguagesType } from '@vben/locales';
|
||||
import type { Locale } from 'ant-design-vue/es/locale';
|
||||
|
||||
import type { App } from 'vue';
|
||||
|
||||
import type { LocaleSetupOptions, SupportedLanguagesType } from '@vben/locales';
|
||||
|
||||
import { ref } from 'vue';
|
||||
|
||||
import {
|
||||
|
@@ -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,
|
||||
|
@@ -1,18 +1,16 @@
|
||||
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,
|
||||
title: $t('page.dashboard.title'),
|
||||
},
|
||||
name: 'Dashboard',
|
||||
path: '/',
|
||||
path: '/dashboard',
|
||||
children: [
|
||||
{
|
||||
name: 'Analytics',
|
||||
|
@@ -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,
|
||||
|
@@ -8,30 +8,20 @@ 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',
|
||||
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',
|
||||
@@ -76,6 +66,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;
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
EchartsUI,
|
||||
type EchartsUIType,
|
||||
useEcharts,
|
||||
} from '@vben/plugins/echarts';
|
||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||
|
||||
const chartRef = ref<EchartsUIType>();
|
||||
const { renderEcharts } = useEcharts(chartRef);
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
EchartsUI,
|
||||
type EchartsUIType,
|
||||
useEcharts,
|
||||
} from '@vben/plugins/echarts';
|
||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||
|
||||
const chartRef = ref<EchartsUIType>();
|
||||
const { renderEcharts } = useEcharts(chartRef);
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
EchartsUI,
|
||||
type EchartsUIType,
|
||||
useEcharts,
|
||||
} from '@vben/plugins/echarts';
|
||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||
|
||||
const chartRef = ref<EchartsUIType>();
|
||||
const { renderEcharts } = useEcharts(chartRef);
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
EchartsUI,
|
||||
type EchartsUIType,
|
||||
useEcharts,
|
||||
} from '@vben/plugins/echarts';
|
||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||
|
||||
const chartRef = ref<EchartsUIType>();
|
||||
const { renderEcharts } = useEcharts(chartRef);
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
EchartsUI,
|
||||
type EchartsUIType,
|
||||
useEcharts,
|
||||
} from '@vben/plugins/echarts';
|
||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||
|
||||
const chartRef = ref<EchartsUIType>();
|
||||
const { renderEcharts } = useEcharts(chartRef);
|
||||
|
@@ -15,10 +15,10 @@ import {
|
||||
} from '@vben/icons';
|
||||
|
||||
import AnalyticsTrends from './analytics-trends.vue';
|
||||
import AnalyticsVisits from './analytics-visits.vue';
|
||||
import AnalyticsVisitsData from './analytics-visits-data.vue';
|
||||
import AnalyticsVisitsSales from './analytics-visits-sales.vue';
|
||||
import AnalyticsVisitsSource from './analytics-visits-source.vue';
|
||||
import AnalyticsVisits from './analytics-visits.vue';
|
||||
|
||||
const overviewItems: AnalysisOverviewItem[] = [
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/web-ele",
|
||||
"version": "5.5.2",
|
||||
"version": "5.5.3",
|
||||
"homepage": "https://vben.pro",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -3,10 +3,11 @@
|
||||
* 可用于 vben-form、vben-modal、vben-drawer 等组件使用,
|
||||
*/
|
||||
|
||||
import type { Component, SetupContext } from 'vue';
|
||||
|
||||
import type { BaseFormComponentType } from '@vben/common-ui';
|
||||
import type { Recordable } from '@vben/types';
|
||||
|
||||
import type { Component, SetupContext } from 'vue';
|
||||
import { h } from 'vue';
|
||||
|
||||
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
||||
|
@@ -1,12 +1,13 @@
|
||||
/**
|
||||
* 该文件可自行根据业务逻辑进行调整
|
||||
*/
|
||||
import type { HttpResponse } from '@vben/request';
|
||||
import type { RequestClientOptions } from '@vben/request';
|
||||
|
||||
import { useAppConfig } from '@vben/hooks';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import {
|
||||
authenticateResponseInterceptor,
|
||||
defaultResponseInterceptor,
|
||||
errorMessageResponseInterceptor,
|
||||
RequestClient,
|
||||
} from '@vben/request';
|
||||
@@ -20,8 +21,9 @@ import { refreshTokenApi } from './core';
|
||||
|
||||
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
||||
|
||||
function createRequestClient(baseURL: string) {
|
||||
function createRequestClient(baseURL: string, options?: RequestClientOptions) {
|
||||
const client = new RequestClient({
|
||||
...options,
|
||||
baseURL,
|
||||
});
|
||||
|
||||
@@ -69,18 +71,14 @@ function createRequestClient(baseURL: string) {
|
||||
},
|
||||
});
|
||||
|
||||
// response数据解构
|
||||
client.addResponseInterceptor<HttpResponse>({
|
||||
fulfilled: (response) => {
|
||||
const { data: responseData, status } = response;
|
||||
|
||||
const { code, data } = responseData;
|
||||
if (status >= 200 && status < 400 && code === 0) {
|
||||
return data;
|
||||
}
|
||||
throw Object.assign({}, response, { response });
|
||||
},
|
||||
});
|
||||
// 处理返回的响应数据格式
|
||||
client.addResponseInterceptor(
|
||||
defaultResponseInterceptor({
|
||||
codeField: 'code',
|
||||
dataField: 'data',
|
||||
successCode: 0,
|
||||
}),
|
||||
);
|
||||
|
||||
// token过期的处理
|
||||
client.addResponseInterceptor(
|
||||
@@ -108,6 +106,8 @@ function createRequestClient(baseURL: string) {
|
||||
return client;
|
||||
}
|
||||
|
||||
export const requestClient = createRequestClient(apiURL);
|
||||
export const requestClient = createRequestClient(apiURL, {
|
||||
responseReturn: 'data',
|
||||
});
|
||||
|
||||
export const baseRequestClient = new RequestClient({ baseURL: apiURL });
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { createApp, watchEffect } from 'vue';
|
||||
|
||||
import { registerAccessDirective } from '@vben/access';
|
||||
import { initTippy } from '@vben/common-ui';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { initStores } from '@vben/stores';
|
||||
import '@vben/styles';
|
||||
@@ -18,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指令
|
||||
@@ -32,6 +41,9 @@ async function bootstrap(namespace: string) {
|
||||
// 安装权限指令
|
||||
registerAccessDirective(app);
|
||||
|
||||
// 初始化 tippy
|
||||
initTippy(app);
|
||||
|
||||
// 配置路由及路由守卫
|
||||
app.use(router);
|
||||
|
||||
|
@@ -1,7 +1,9 @@
|
||||
import type { LocaleSetupOptions, SupportedLanguagesType } from '@vben/locales';
|
||||
import type { Language } from 'element-plus/es/locale';
|
||||
|
||||
import type { App } from 'vue';
|
||||
|
||||
import type { LocaleSetupOptions, SupportedLanguagesType } from '@vben/locales';
|
||||
|
||||
import { ref } from 'vue';
|
||||
|
||||
import {
|
||||
|
@@ -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,
|
||||
|
@@ -1,18 +1,16 @@
|
||||
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,
|
||||
title: $t('page.dashboard.title'),
|
||||
},
|
||||
name: 'Dashboard',
|
||||
path: '/',
|
||||
path: '/dashboard',
|
||||
children: [
|
||||
{
|
||||
name: 'Analytics',
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
EchartsUI,
|
||||
type EchartsUIType,
|
||||
useEcharts,
|
||||
} from '@vben/plugins/echarts';
|
||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||
|
||||
const chartRef = ref<EchartsUIType>();
|
||||
const { renderEcharts } = useEcharts(chartRef);
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
EchartsUI,
|
||||
type EchartsUIType,
|
||||
useEcharts,
|
||||
} from '@vben/plugins/echarts';
|
||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||
|
||||
const chartRef = ref<EchartsUIType>();
|
||||
const { renderEcharts } = useEcharts(chartRef);
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
EchartsUI,
|
||||
type EchartsUIType,
|
||||
useEcharts,
|
||||
} from '@vben/plugins/echarts';
|
||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||
|
||||
const chartRef = ref<EchartsUIType>();
|
||||
const { renderEcharts } = useEcharts(chartRef);
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
EchartsUI,
|
||||
type EchartsUIType,
|
||||
useEcharts,
|
||||
} from '@vben/plugins/echarts';
|
||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||
|
||||
const chartRef = ref<EchartsUIType>();
|
||||
const { renderEcharts } = useEcharts(chartRef);
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
EchartsUI,
|
||||
type EchartsUIType,
|
||||
useEcharts,
|
||||
} from '@vben/plugins/echarts';
|
||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||
|
||||
const chartRef = ref<EchartsUIType>();
|
||||
const { renderEcharts } = useEcharts(chartRef);
|
||||
|
@@ -15,10 +15,10 @@ import {
|
||||
} from '@vben/icons';
|
||||
|
||||
import AnalyticsTrends from './analytics-trends.vue';
|
||||
import AnalyticsVisits from './analytics-visits.vue';
|
||||
import AnalyticsVisitsData from './analytics-visits-data.vue';
|
||||
import AnalyticsVisitsSales from './analytics-visits-sales.vue';
|
||||
import AnalyticsVisitsSource from './analytics-visits-source.vue';
|
||||
import AnalyticsVisits from './analytics-visits.vue';
|
||||
|
||||
const overviewItems: AnalysisOverviewItem[] = [
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/web-naive",
|
||||
"version": "5.5.2",
|
||||
"version": "5.5.3",
|
||||
"homepage": "https://vben.pro",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -3,9 +3,10 @@
|
||||
* 可用于 vben-form、vben-modal、vben-drawer 等组件使用,
|
||||
*/
|
||||
|
||||
import type { Component, SetupContext } from 'vue';
|
||||
|
||||
import type { BaseFormComponentType } from '@vben/common-ui';
|
||||
|
||||
import type { Component, SetupContext } from 'vue';
|
||||
import { h } from 'vue';
|
||||
|
||||
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
||||
|
@@ -1,12 +1,13 @@
|
||||
/**
|
||||
* 该文件可自行根据业务逻辑进行调整
|
||||
*/
|
||||
import type { HttpResponse } from '@vben/request';
|
||||
import type { RequestClientOptions } from '@vben/request';
|
||||
|
||||
import { useAppConfig } from '@vben/hooks';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import {
|
||||
authenticateResponseInterceptor,
|
||||
defaultResponseInterceptor,
|
||||
errorMessageResponseInterceptor,
|
||||
RequestClient,
|
||||
} from '@vben/request';
|
||||
@@ -19,8 +20,9 @@ import { refreshTokenApi } from './core';
|
||||
|
||||
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
||||
|
||||
function createRequestClient(baseURL: string) {
|
||||
function createRequestClient(baseURL: string, options?: RequestClientOptions) {
|
||||
const client = new RequestClient({
|
||||
...options,
|
||||
baseURL,
|
||||
});
|
||||
|
||||
@@ -68,18 +70,14 @@ function createRequestClient(baseURL: string) {
|
||||
},
|
||||
});
|
||||
|
||||
// response数据解构
|
||||
client.addResponseInterceptor<HttpResponse>({
|
||||
fulfilled: (response) => {
|
||||
const { data: responseData, status } = response;
|
||||
|
||||
const { code, data } = responseData;
|
||||
if (status >= 200 && status < 400 && code === 0) {
|
||||
return data;
|
||||
}
|
||||
throw Object.assign({}, response, { response });
|
||||
},
|
||||
});
|
||||
// 处理返回的响应数据格式
|
||||
client.addResponseInterceptor(
|
||||
defaultResponseInterceptor({
|
||||
codeField: 'code',
|
||||
dataField: 'data',
|
||||
successCode: 0,
|
||||
}),
|
||||
);
|
||||
|
||||
// token过期的处理
|
||||
client.addResponseInterceptor(
|
||||
@@ -107,6 +105,8 @@ function createRequestClient(baseURL: string) {
|
||||
return client;
|
||||
}
|
||||
|
||||
export const requestClient = createRequestClient(apiURL);
|
||||
export const requestClient = createRequestClient(apiURL, {
|
||||
responseReturn: 'data',
|
||||
});
|
||||
|
||||
export const baseRequestClient = new RequestClient({ baseURL: apiURL });
|
||||
|
@@ -1,9 +1,11 @@
|
||||
import { createApp, watchEffect } from 'vue';
|
||||
|
||||
import { registerAccessDirective } from '@vben/access';
|
||||
import { initTippy } from '@vben/common-ui';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { initStores } from '@vben/stores';
|
||||
import '@vben/styles';
|
||||
import '@vben/styles/naive';
|
||||
|
||||
import { useTitle } from '@vueuse/core';
|
||||
|
||||
@@ -16,6 +18,16 @@ import { router } from './router';
|
||||
async function bootstrap(namespace: string) {
|
||||
// 初始化组件适配器
|
||||
initComponentAdapter();
|
||||
|
||||
// // 设置弹窗的默认配置
|
||||
// setDefaultModalProps({
|
||||
// fullscreenButton: false,
|
||||
// });
|
||||
// // 设置抽屉的默认配置
|
||||
// setDefaultDrawerProps({
|
||||
// // zIndex: 2000,
|
||||
// });
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
// 国际化 i18n 配置
|
||||
@@ -27,6 +39,9 @@ async function bootstrap(namespace: string) {
|
||||
// 安装权限指令
|
||||
registerAccessDirective(app);
|
||||
|
||||
// 初始化 tippy
|
||||
initTippy(app);
|
||||
|
||||
// 配置路由及路由守卫
|
||||
app.use(router);
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import type { LocaleSetupOptions, SupportedLanguagesType } from '@vben/locales';
|
||||
|
||||
import type { App } from 'vue';
|
||||
|
||||
import type { LocaleSetupOptions, SupportedLanguagesType } from '@vben/locales';
|
||||
|
||||
import {
|
||||
$t,
|
||||
setupI18n as coreSetup,
|
||||
|
@@ -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,
|
||||
|
@@ -1,18 +1,16 @@
|
||||
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,
|
||||
title: $t('page.dashboard.title'),
|
||||
},
|
||||
name: 'Dashboard',
|
||||
path: '/',
|
||||
path: '/dashboard',
|
||||
children: [
|
||||
{
|
||||
name: 'Analytics',
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
EchartsUI,
|
||||
type EchartsUIType,
|
||||
useEcharts,
|
||||
} from '@vben/plugins/echarts';
|
||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||
|
||||
const chartRef = ref<EchartsUIType>();
|
||||
const { renderEcharts } = useEcharts(chartRef);
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
EchartsUI,
|
||||
type EchartsUIType,
|
||||
useEcharts,
|
||||
} from '@vben/plugins/echarts';
|
||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||
|
||||
const chartRef = ref<EchartsUIType>();
|
||||
const { renderEcharts } = useEcharts(chartRef);
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
EchartsUI,
|
||||
type EchartsUIType,
|
||||
useEcharts,
|
||||
} from '@vben/plugins/echarts';
|
||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||
|
||||
const chartRef = ref<EchartsUIType>();
|
||||
const { renderEcharts } = useEcharts(chartRef);
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
EchartsUI,
|
||||
type EchartsUIType,
|
||||
useEcharts,
|
||||
} from '@vben/plugins/echarts';
|
||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||
|
||||
const chartRef = ref<EchartsUIType>();
|
||||
const { renderEcharts } = useEcharts(chartRef);
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import {
|
||||
EchartsUI,
|
||||
type EchartsUIType,
|
||||
useEcharts,
|
||||
} from '@vben/plugins/echarts';
|
||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||
|
||||
const chartRef = ref<EchartsUIType>();
|
||||
const { renderEcharts } = useEcharts(chartRef);
|
||||
|
@@ -15,10 +15,10 @@ import {
|
||||
} from '@vben/icons';
|
||||
|
||||
import AnalyticsTrends from './analytics-trends.vue';
|
||||
import AnalyticsVisits from './analytics-visits.vue';
|
||||
import AnalyticsVisitsData from './analytics-visits-data.vue';
|
||||
import AnalyticsVisitsSales from './analytics-visits-sales.vue';
|
||||
import AnalyticsVisitsSource from './analytics-visits-source.vue';
|
||||
import AnalyticsVisits from './analytics-visits.vue';
|
||||
|
||||
const overviewItems: AnalysisOverviewItem[] = [
|
||||
{
|
||||
|
@@ -40,6 +40,7 @@ const [Form, formApi] = useVbenForm({
|
||||
fieldName: 'api',
|
||||
// 界面显示的label
|
||||
label: 'ApiSelect',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'ApiTreeSelect',
|
||||
@@ -56,16 +57,19 @@ const [Form, formApi] = useVbenForm({
|
||||
fieldName: 'apiTree',
|
||||
// 界面显示的label
|
||||
label: 'ApiTreeSelect',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'string',
|
||||
label: 'String',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'number',
|
||||
label: 'Number',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'RadioGroup',
|
||||
@@ -80,6 +84,7 @@ const [Form, formApi] = useVbenForm({
|
||||
{ value: 'E', label: 'E' },
|
||||
],
|
||||
},
|
||||
rules: 'selectRequired',
|
||||
},
|
||||
{
|
||||
component: 'RadioGroup',
|
||||
@@ -94,9 +99,9 @@ const [Form, formApi] = useVbenForm({
|
||||
{ value: 'C', label: '选项C' },
|
||||
{ value: 'D', label: '选项D' },
|
||||
{ value: 'E', label: '选项E' },
|
||||
{ value: 'F', label: '选项F' },
|
||||
],
|
||||
},
|
||||
rules: 'selectRequired',
|
||||
},
|
||||
{
|
||||
component: 'CheckboxGroup',
|
||||
@@ -109,11 +114,22 @@ const [Form, formApi] = useVbenForm({
|
||||
{ value: 'C', label: '选项C' },
|
||||
],
|
||||
},
|
||||
rules: 'selectRequired',
|
||||
},
|
||||
{
|
||||
component: 'DatePicker',
|
||||
fieldName: 'date',
|
||||
label: 'Date',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'textArea',
|
||||
label: 'TextArea',
|
||||
componentProps: {
|
||||
type: 'textarea',
|
||||
},
|
||||
rules: 'required',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<script lang="ts" setup>
|
||||
import type { NotificationType } from 'naive-ui';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
|
||||
import { type NotificationType } from 'naive-ui';
|
||||
import { NButton, NCard, NSpace, useMessage, useNotification } from 'naive-ui';
|
||||
|
||||
const notification = useNotification();
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { SetupContext } from 'vue';
|
||||
|
||||
import { computed, ref, useSlots } from 'vue';
|
||||
|
||||
import { VbenTooltip } from '@vben-core/shadcn-ui';
|
||||
@@ -25,7 +27,7 @@ const props = withDefaults(
|
||||
|
||||
const open = ref(false);
|
||||
|
||||
const slots = useSlots();
|
||||
const slots: SetupContext['slots'] = useSlots();
|
||||
|
||||
const tabs = computed(() => {
|
||||
return props.files.map((file) => {
|
||||
|
@@ -1,4 +1,6 @@
|
||||
import { type DefaultTheme, defineConfig } from 'vitepress';
|
||||
import type { DefaultTheme } from 'vitepress';
|
||||
|
||||
import { defineConfig } from 'vitepress';
|
||||
|
||||
import { version } from '../../../package.json';
|
||||
|
||||
|
@@ -1,4 +1,6 @@
|
||||
import { type DefaultTheme, defineConfig } from 'vitepress';
|
||||
import type { DefaultTheme } from 'vitepress';
|
||||
|
||||
import { defineConfig } from 'vitepress';
|
||||
|
||||
import { version } from '../../../package.json';
|
||||
|
||||
|
@@ -10,7 +10,6 @@ import {
|
||||
|
||||
// import { useAntdDesignTokens } from '@vben/hooks';
|
||||
// import { initPreferences } from '@vben/preferences';
|
||||
|
||||
import { ConfigProvider, theme } from 'ant-design-vue';
|
||||
import mediumZoom from 'medium-zoom';
|
||||
import { useRoute } from 'vitepress';
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/docs",
|
||||
"version": "5.5.2",
|
||||
"version": "5.5.3",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "vitepress build",
|
||||
|
@@ -3,9 +3,10 @@
|
||||
* 可用于 vben-form、vben-modal、vben-drawer 等组件使用,
|
||||
*/
|
||||
|
||||
import type { Component, SetupContext } from 'vue';
|
||||
|
||||
import type { BaseFormComponentType } from '@vben/common-ui';
|
||||
|
||||
import type { Component, SetupContext } from 'vue';
|
||||
import { h } from 'vue';
|
||||
|
||||
import { globalShareState } from '@vben/common-ui';
|
||||
|
@@ -129,7 +129,8 @@ function fetchApi(): Promise<Record<string, any>> {
|
||||
|
||||
| 属性名 | 描述 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| component | 欲包装的组件 | `Component` | - |
|
||||
| modelValue(v-model) | 当前值 | `any` | - |
|
||||
| component | 欲包装的组件(以下称为目标组件) | `Component` | - |
|
||||
| numberToString | 是否将value从数字转为string | `boolean` | `false` |
|
||||
| api | 获取数据的函数 | `(arg?: any) => Promise<OptionsItem[] \| Record<string, any>>` | - |
|
||||
| params | 传递给api的参数 | `Record<string, any>` | - |
|
||||
@@ -137,16 +138,12 @@ function fetchApi(): Promise<Record<string, any>> {
|
||||
| labelField | label字段名 | `string` | `label` |
|
||||
| childrenField | 子级数据字段名,需要层级数据的组件可用 | `string` | `` |
|
||||
| valueField | value字段名 | `string` | `value` |
|
||||
| optionsPropName | 组件接收options数据的属性名称 | `string` | `options` |
|
||||
| modelPropName | 组件的双向绑定属性名,默认为modelValue。部分组件可能为value | `string` | `modelValue` |
|
||||
| optionsPropName | 目标组件接收options数据的属性名称 | `string` | `options` |
|
||||
| modelPropName | 目标组件的双向绑定属性名,默认为modelValue。部分组件可能为value | `string` | `modelValue` |
|
||||
| immediate | 是否立即调用api | `boolean` | `true` |
|
||||
| alwaysLoad | 每次`visibleEvent`事件发生时都重新请求数据 | `boolean` | `false` |
|
||||
| beforeFetch | 在api请求之前的回调函数 | `AnyPromiseFunction<any, any>` | - |
|
||||
| afterFetch | 在api请求之后的回调函数 | `AnyPromiseFunction<any, any>` | - |
|
||||
| options | 直接传入选项数据,也作为api返回空数据时的后备数据 | `OptionsItem[]` | - |
|
||||
| visibleEvent | 触发重新请求数据的事件名 | `string` | - |
|
||||
| loadingSlot | 组件的插槽名称,用来显示一个"加载中"的图标 | `string` | - |
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
| loadingSlot | 目标组件的插槽名称,用来显示一个"加载中"的图标 | `string` | - |
|
||||
|
@@ -54,6 +54,8 @@ 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等。
|
||||
|
||||
:::
|
||||
|
||||
@@ -75,12 +77,15 @@ const [Drawer, drawerApi] = useVbenDrawer({
|
||||
| 属性名 | 描述 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| appendToMain | 是否挂载到内容区域(默认挂载到body) | `boolean` | `false` |
|
||||
| connectedComponent | 连接另一个Modal组件 | `Component` | - |
|
||||
| destroyOnClose | 关闭时销毁`connectedComponent` | `boolean` | `false` |
|
||||
| title | 标题 | `string\|slot` | - |
|
||||
| titleTooltip | 标题提示信息 | `string\|slot` | - |
|
||||
| description | 描述信息 | `string\|slot` | - |
|
||||
| isOpen | 弹窗打开状态 | `boolean` | `false` |
|
||||
| loading | 弹窗加载状态 | `boolean` | `false` |
|
||||
| closable | 显示关闭按钮 | `boolean` | `true` |
|
||||
| closeIconPlacement | 关闭按钮位置 | `'left'\|'right'` | `right` |
|
||||
| modal | 显示遮罩 | `boolean` | `true` |
|
||||
| header | 显示header | `boolean` | `true` |
|
||||
| footer | 显示footer | `boolean\|slot` | `true` |
|
||||
@@ -97,6 +102,7 @@ const [Drawer, drawerApi] = useVbenDrawer({
|
||||
| footerClass | modal底部区域的class | `string` | - |
|
||||
| headerClass | modal顶部区域的class | `string` | - |
|
||||
| zIndex | 抽屉的ZIndex层级 | `number` | `1000` |
|
||||
| overlayBlur | 遮罩模糊度 | `number` | - |
|
||||
|
||||
::: info appendToMain
|
||||
|
||||
@@ -108,12 +114,14 @@ const [Drawer, drawerApi] = useVbenDrawer({
|
||||
|
||||
以下事件,只有在 `useVbenDrawer({onCancel:()=>{}})` 中传入才会生效。
|
||||
|
||||
| 事件名 | 描述 | 类型 |
|
||||
| --- | --- | --- |
|
||||
| onBeforeClose | 关闭前触发,返回 `false`则禁止关闭 | `()=>boolean` |
|
||||
| onCancel | 点击取消按钮触发 | `()=>void` |
|
||||
| onConfirm | 点击确认按钮触发 | `()=>void` |
|
||||
| onOpenChange | 关闭或者打开弹窗时触发 | `(isOpen:boolean)=>void` |
|
||||
| 事件名 | 描述 | 类型 | 版本限制 |
|
||||
| --- | --- | --- | --- |
|
||||
| onBeforeClose | 关闭前触发,返回 `false`则禁止关闭 | `()=>boolean` | --- |
|
||||
| onCancel | 点击取消按钮触发 | `()=>void` | --- |
|
||||
| onClosed | 关闭动画播放完毕时触发 | `()=>void` | >5.5.2 |
|
||||
| onConfirm | 点击确认按钮触发 | `()=>void` | --- |
|
||||
| onOpenChange | 关闭或者打开弹窗时触发 | `(isOpen:boolean)=>void` | --- |
|
||||
| onOpened | 打开动画播放完毕时触发 | `()=>void` | >5.5.2 |
|
||||
|
||||
### Slots
|
||||
|
||||
@@ -124,14 +132,16 @@ const [Drawer, drawerApi] = useVbenDrawer({
|
||||
| default | 默认插槽 - 弹窗内容 |
|
||||
| prepend-footer | 取消按钮左侧 |
|
||||
| append-footer | 取消按钮右侧 |
|
||||
| close-icon | 关闭按钮图标 |
|
||||
| extra | 额外内容(标题右侧) |
|
||||
|
||||
### modalApi
|
||||
### drawerApi
|
||||
|
||||
| 事件名 | 描述 | 类型 |
|
||||
| 方法 | 描述 | 类型 |
|
||||
| --- | --- | --- |
|
||||
| setState | 动态设置弹窗状态属性 | `setState(props) \| setState((prev)=>(props))` |
|
||||
| setState | 动态设置弹窗状态属性 | `(((prev: ModalState) => Partial<ModalState>)\| Partial<ModalState>)=>drawerApi` |
|
||||
| open | 打开弹窗 | `()=>void` |
|
||||
| close | 关闭弹窗 | `()=>void` |
|
||||
| setData | 设置共享数据 | `<T>(data:T)=>void` |
|
||||
| setData | 设置共享数据 | `<T>(data:T)=>drawerApi` |
|
||||
| getData | 获取共享数据 | `<T>()=>T` |
|
||||
| useStore | 获取可响应式状态 | - |
|
||||
|
@@ -316,12 +316,18 @@ useVbenForm 返回的第二个参数,是一个对象,包含了一些表单
|
||||
| collapsed | 是否折叠,在`showCollapseButton`为`true`时生效 | `boolean` | `false` |
|
||||
| collapseTriggerResize | 折叠时,触发`resize`事件 | `boolean` | `false` |
|
||||
| collapsedRows | 折叠时保持的行数 | `number` | `1` |
|
||||
| fieldMappingTime | 用于将表单内时间区域组件的数组值映射成 2 个字段 | `[string, [string, string], string?][]` | - |
|
||||
| fieldMappingTime | 用于将表单内的数组值值映射成 2 个字段 | `[string, [string, string],Nullable<string>\|[string,string]\|((any,string)=>any)?][]` | - |
|
||||
| commonConfig | 表单项的通用配置,每个配置都会传递到每个表单项,表单项可覆盖 | `FormCommonConfig` | - |
|
||||
| schema | 表单项的每一项配置 | `FormSchema[]` | - |
|
||||
| submitOnEnter | 按下回车健时提交表单 | `boolean` | false |
|
||||
| submitOnChange | 字段值改变时提交表单(内部防抖,这个属性一般用于表格的搜索表单) | `boolean` | false |
|
||||
|
||||
::: tip fieldMappingTime
|
||||
|
||||
此属性用于将表单内的数组值映射成 2 个字段,它应当传入一个数组,数组的每一项是一个映射规则,规则的第一个成员是一个字符串,表示需要映射的字段名,第二个成员是一个数组,表示映射后的字段名,第三个成员是一个可选的格式掩码,用于格式化日期时间字段;也可以提供一个格式化函数(参数分别为当前值和当前字段名,返回格式化后的值)。如果明确地将格式掩码设为null,则原值映射而不进行格式化(适用于非日期时间字段)。例如:`[['timeRange', ['startTime', 'endTime'], 'YYYY-MM-DD']]`,`timeRange`应当是一个至少具有2个成员的数组类型的值。Form会将`timeRange`的值前两个值分别按照格式掩码`YYYY-MM-DD`格式化后映射到`startTime`和`endTime`字段上。每一项的第三个参数是一个可选的格式掩码,
|
||||
|
||||
:::
|
||||
|
||||
### TS 类型说明
|
||||
|
||||
::: details ActionButtonOptions
|
||||
@@ -406,6 +412,11 @@ export interface FormCommonConfig {
|
||||
* 所有表单项的label宽度
|
||||
*/
|
||||
labelWidth?: number;
|
||||
/**
|
||||
* 所有表单项的model属性名。使用自定义组件时可通过此配置指定组件的model属性名。已经在modelPropNameMap中注册的组件不受此配置影响
|
||||
* @default "modelValue"
|
||||
*/
|
||||
modelPropName?: string;
|
||||
/**
|
||||
* 所有表单项的wrapper样式
|
||||
*/
|
||||
|
@@ -60,6 +60,8 @@ 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等。
|
||||
|
||||
:::
|
||||
|
||||
@@ -81,6 +83,8 @@ const [Modal, modalApi] = useVbenModal({
|
||||
| 属性名 | 描述 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| appendToMain | 是否挂载到内容区域(默认挂载到body) | `boolean` | `false` |
|
||||
| connectedComponent | 连接另一个Modal组件 | `Component` | - |
|
||||
| destroyOnClose | 关闭时销毁`connectedComponent` | `boolean` | `false` |
|
||||
| title | 标题 | `string\|slot` | - |
|
||||
| titleTooltip | 标题提示信息 | `string\|slot` | - |
|
||||
| description | 描述信息 | `string\|slot` | - |
|
||||
@@ -108,6 +112,8 @@ const [Modal, modalApi] = useVbenModal({
|
||||
| headerClass | modal顶部区域的class | `string` | - |
|
||||
| bordered | 是否显示border | `boolean` | `false` |
|
||||
| zIndex | 弹窗的ZIndex层级 | `number` | `1000` |
|
||||
| overlayBlur | 遮罩模糊度 | `number` | - |
|
||||
| submitting | 标记为提交中,锁定弹窗当前状态 | `boolean` | `false` |
|
||||
|
||||
::: info appendToMain
|
||||
|
||||
@@ -121,7 +127,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
|
||||
| 事件名 | 描述 | 类型 | 版本号 |
|
||||
| --- | --- | --- | --- |
|
||||
| onBeforeClose | 关闭前触发,返回 `false`则禁止关闭 | `()=>boolean` | |
|
||||
| onBeforeClose | 关闭前触发,返回 `false`或者被`reject`则禁止关闭 | `()=>Promise<boolean>\|boolean` | >5.5.2支持Promise |
|
||||
| onCancel | 点击取消按钮触发 | `()=>void` | |
|
||||
| onClosed | 关闭动画播放完毕时触发 | `()=>void` | >5.4.3 |
|
||||
| onConfirm | 点击确认按钮触发 | `()=>void` | |
|
||||
@@ -140,11 +146,18 @@ const [Modal, modalApi] = useVbenModal({
|
||||
|
||||
### modalApi
|
||||
|
||||
| 事件名 | 描述 | 类型 |
|
||||
| --- | --- | --- |
|
||||
| setState | 动态设置弹窗状态属性 | `setState(props) \| setState((prev)=>(props))` |
|
||||
| open | 打开弹窗 | `()=>void` |
|
||||
| close | 关闭弹窗 | `()=>void` |
|
||||
| setData | 设置共享数据 | `<T>(data:T)=>void` |
|
||||
| getData | 获取共享数据 | `<T>()=>T` |
|
||||
| useStore | 获取可响应式状态 | - |
|
||||
| 方法 | 描述 | 类型 | 版本 |
|
||||
| --- | --- | --- | --- |
|
||||
| setState | 动态设置弹窗状态属性 | `(((prev: ModalState) => Partial<ModalState>)\| Partial<ModalState>)=>modalApi` | - |
|
||||
| open | 打开弹窗 | `()=>void` | - |
|
||||
| close | 关闭弹窗 | `()=>void` | - |
|
||||
| setData | 设置共享数据 | `<T>(data:T)=>modalApi` | - |
|
||||
| getData | 获取共享数据 | `<T>()=>T` | - |
|
||||
| useStore | 获取可响应式状态 | - | - |
|
||||
| lock | 将弹窗标记为提交中,锁定当前状态 | `(isLock:boolean)=>modalApi` | >5.5.2 |
|
||||
|
||||
::: info lock
|
||||
|
||||
`lock`方法用于锁定当前弹窗的状态,一般用于提交数据的过程中防止用户重复提交或者弹窗被意外关闭、表单数据被改变等等。当处于锁定状态时,弹窗的确认按钮会变为loading状态,同时禁用确认按钮、隐藏关闭按钮、禁止ESC或者点击遮罩等方式关闭弹窗、开启弹窗的spinner动画以遮挡弹窗内容。调用`close`方法关闭处于锁定状态的弹窗时,会自动解锁。
|
||||
|
||||
:::
|
||||
|
@@ -13,8 +13,7 @@ function open() {
|
||||
}
|
||||
|
||||
function handleUpdateTitle() {
|
||||
drawerApi.setState({ title: '外部动态标题' });
|
||||
drawerApi.open();
|
||||
drawerApi.setState({ title: '外部动态标题' }).open();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@@ -9,11 +9,12 @@ const [Drawer, drawerApi] = useVbenDrawer({
|
||||
});
|
||||
|
||||
function open() {
|
||||
drawerApi.setData({
|
||||
content: '外部传递的数据 content',
|
||||
payload: '外部传递的数据 payload',
|
||||
});
|
||||
drawerApi.open();
|
||||
drawerApi
|
||||
.setData({
|
||||
content: '外部传递的数据 content',
|
||||
payload: '外部传递的数据 payload',
|
||||
})
|
||||
.open();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@@ -13,8 +13,7 @@ function openModal() {
|
||||
}
|
||||
|
||||
function handleUpdateTitle() {
|
||||
modalApi.setState({ title: '外部动态标题' });
|
||||
modalApi.open();
|
||||
modalApi.setState({ title: '外部动态标题' }).open();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@@ -9,11 +9,12 @@ const [Modal, modalApi] = useVbenModal({
|
||||
});
|
||||
|
||||
function openModal() {
|
||||
modalApi.setData({
|
||||
content: '外部传递的数据 content',
|
||||
payload: '外部传递的数据 payload',
|
||||
});
|
||||
modalApi.open();
|
||||
modalApi
|
||||
.setData({
|
||||
content: '外部传递的数据 content',
|
||||
payload: '外部传递的数据 payload',
|
||||
})
|
||||
.open();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@@ -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'),
|
||||
|
@@ -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`。
|
||||
|
||||
## 路由刷新
|
||||
|
||||
路由刷新方式如下:
|
||||
|
@@ -67,7 +67,7 @@ pnpm install
|
||||
::: tip 注意
|
||||
|
||||
- 项目只支持使用 `pnpm` 进行依赖安装,默认会使用 `corepack` 来安装指定版本的 `pnpm`。:
|
||||
- 如果你的网络环境无法访问npm源,你可以设置系统的环境变量`COREPACK_REGISTRY=https://registry.npmmirror.com`,然后再执行`pnpm install`。
|
||||
- 如果你的网络环境无法访问npm源,你可以设置系统的环境变量`COREPACK_NPM_REGISTRY=https://registry.npmmirror.com`,然后再执行`pnpm install`。
|
||||
- 如果你不想使用`corepack`,你需要禁用`corepack`,然后使用你自己的`pnpm`进行安装。
|
||||
|
||||
:::
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/commitlint-config",
|
||||
"version": "5.5.2",
|
||||
"version": "5.5.3",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
|
@@ -10,6 +10,7 @@ export async function importPluginConfig(): Promise<Linter.Config[]> {
|
||||
import: pluginImport,
|
||||
},
|
||||
rules: {
|
||||
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
|
||||
'import/first': 'error',
|
||||
'import/newline-after-import': 'error',
|
||||
'import/no-duplicates': 'error',
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import type { Linter } from 'eslint';
|
||||
|
||||
// @ts-expect-error - no types
|
||||
import js from '@eslint/js';
|
||||
import pluginUnusedImports from 'eslint-plugin-unused-imports';
|
||||
import globals from 'globals';
|
||||
|
@@ -1,8 +1,13 @@
|
||||
import type { Linter } from 'eslint';
|
||||
|
||||
import perfectionistPlugin from 'eslint-plugin-perfectionist';
|
||||
import { interopDefault } from '../util';
|
||||
|
||||
export async function perfectionist(): Promise<Linter.Config[]> {
|
||||
const perfectionistPlugin = await interopDefault(
|
||||
// @ts-expect-error - no types
|
||||
import('eslint-plugin-perfectionist'),
|
||||
);
|
||||
|
||||
return [
|
||||
perfectionistPlugin.configs['recommended-natural'],
|
||||
{
|
||||
@@ -19,21 +24,28 @@ export async function perfectionist(): Promise<Linter.Config[]> {
|
||||
{
|
||||
customGroups: {
|
||||
type: {
|
||||
vben: 'vben',
|
||||
vue: 'vue',
|
||||
'vben-core-type': ['^@vben-core/.+'],
|
||||
'vben-type': ['^@vben/.+'],
|
||||
'vue-type': ['^vue$', '^vue-.+', '^@vue/.+'],
|
||||
},
|
||||
value: {
|
||||
vben: ['@vben*', '@vben/**/**', '@vben-core/**/**'],
|
||||
vue: ['vue', 'vue-*', '@vue*'],
|
||||
vben: ['^@vben/.+'],
|
||||
'vben-core': ['^@vben-core/.+'],
|
||||
vue: ['^vue$', '^vue-.+', '^@vue/.+'],
|
||||
},
|
||||
},
|
||||
environment: 'node',
|
||||
groups: [
|
||||
['external-type', 'builtin-type', 'type'],
|
||||
'vue-type',
|
||||
'vben-type',
|
||||
'vben-core-type',
|
||||
['parent-type', 'sibling-type', 'index-type'],
|
||||
['internal-type'],
|
||||
'builtin',
|
||||
'vue',
|
||||
'vben',
|
||||
'vben-core',
|
||||
'external',
|
||||
'internal',
|
||||
['parent', 'sibling', 'index'],
|
||||
@@ -43,12 +55,13 @@ export async function perfectionist(): Promise<Linter.Config[]> {
|
||||
'object',
|
||||
'unknown',
|
||||
],
|
||||
internalPattern: ['#*', '#*/**'],
|
||||
internalPattern: ['^#/.+'],
|
||||
newlinesBetween: 'always',
|
||||
order: 'asc',
|
||||
type: 'natural',
|
||||
},
|
||||
],
|
||||
'perfectionist/sort-modules': 'off',
|
||||
'perfectionist/sort-named-exports': [
|
||||
'error',
|
||||
{
|
||||
@@ -67,42 +80,6 @@ export async function perfectionist(): Promise<Linter.Config[]> {
|
||||
groups: ['unknown', 'items', 'list', 'children'],
|
||||
ignorePattern: ['children'],
|
||||
order: 'asc',
|
||||
partitionByComment: 'Part:**',
|
||||
type: 'natural',
|
||||
},
|
||||
],
|
||||
'perfectionist/sort-vue-attributes': [
|
||||
'error',
|
||||
{
|
||||
// Based on: https://vuejs.org/style-guide/rules-recommended.html#element-attribute-order
|
||||
customGroups: {
|
||||
/* eslint-disable perfectionist/sort-objects */
|
||||
DEFINITION: '*(is|:is|v-is)',
|
||||
LIST_RENDERING: 'v-for',
|
||||
CONDITIONALS: 'v-*(else-if|if|else|show|cloak)',
|
||||
RENDER_MODIFIERS: 'v-*(pre|once)',
|
||||
GLOBAL: '*(:id|id)',
|
||||
UNIQUE: '*(ref|key|:ref|:key)',
|
||||
SLOT: '*(v-slot|slot)',
|
||||
TWO_WAY_BINDING: '*(v-model|v-model:*)',
|
||||
// OTHER_DIRECTIVES e.g. 'v-custom-directive'
|
||||
EVENTS: '*(v-on|@*)',
|
||||
CONTENT: 'v-*(html|text)',
|
||||
/* eslint-enable perfectionist/sort-objects */
|
||||
},
|
||||
groups: [
|
||||
'DEFINITION',
|
||||
'LIST_RENDERING',
|
||||
'CONDITIONALS',
|
||||
'RENDER_MODIFIERS',
|
||||
'GLOBAL',
|
||||
'UNIQUE',
|
||||
'SLOT',
|
||||
'TWO_WAY_BINDING',
|
||||
'unknown',
|
||||
'EVENTS',
|
||||
'CONTENT',
|
||||
],
|
||||
type: 'natural',
|
||||
},
|
||||
],
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/stylelint-config",
|
||||
"version": "5.5.2",
|
||||
"version": "5.5.3",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/node-utils",
|
||||
"version": "5.5.2",
|
||||
"version": "5.5.3",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
|
@@ -2,7 +2,7 @@ export * from './constants';
|
||||
export * from './date';
|
||||
export * from './fs';
|
||||
export * from './git';
|
||||
export { add as gitAdd, getStagedFiles } from './git';
|
||||
export { getStagedFiles, add as gitAdd } from './git';
|
||||
export { generatorContentHash } from './hash';
|
||||
export * from './monorepo';
|
||||
export { toPosixPath } from './path';
|
||||
|
@@ -1,4 +1,6 @@
|
||||
import ora, { type Ora } from 'ora';
|
||||
import type { Ora } from 'ora';
|
||||
|
||||
import ora from 'ora';
|
||||
|
||||
interface SpinnerOptions {
|
||||
failedText?: string;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/tailwind-config",
|
||||
"version": "5.5.2",
|
||||
"version": "5.5.3",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
|
@@ -130,7 +130,6 @@ export default {
|
||||
enterAnimationPlugin,
|
||||
],
|
||||
prefix: '',
|
||||
safelist: ['dark'],
|
||||
theme: {
|
||||
container: {
|
||||
center: true,
|
||||
@@ -202,6 +201,7 @@ export default {
|
||||
},
|
||||
},
|
||||
},
|
||||
safelist: ['dark'],
|
||||
} as Config;
|
||||
|
||||
function createColorsPalette(name: string) {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/tsconfig",
|
||||
"version": "5.5.2",
|
||||
"version": "5.5.3",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/vite-config",
|
||||
"version": "5.5.2",
|
||||
"version": "5.5.3",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
|
@@ -10,11 +10,11 @@ import { minify } from 'html-minifier-terser';
|
||||
|
||||
const DEFAULT_PROVIDER = 'jspm.io';
|
||||
|
||||
type pluginOptions = {
|
||||
type pluginOptions = GeneratorOptions & {
|
||||
debug?: boolean;
|
||||
defaultProvider?: 'esm.sh' | 'jsdelivr' | 'jspm.io';
|
||||
importmap?: Array<{ name: string; range?: string }>;
|
||||
} & GeneratorOptions;
|
||||
};
|
||||
|
||||
// async function getLatestVersionOfShims() {
|
||||
// const result = await fetch('https://ga.jspm.io/npm:es-module-shims');
|
||||
|
@@ -1,3 +1,5 @@
|
||||
import type { PluginOption } from 'vite';
|
||||
|
||||
import fs from 'node:fs';
|
||||
import fsp from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
@@ -5,8 +7,6 @@ import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { readPackageJSON } from '@vben/node-utils';
|
||||
|
||||
import { type PluginOption } from 'vite';
|
||||
|
||||
/**
|
||||
* 用于生成将loading样式注入到项目中
|
||||
* 为多app提供loading样式,无需在每个 app -> index.html单独引入
|
||||
|
@@ -67,11 +67,11 @@ async function loadAndConvertEnv(
|
||||
match = 'VITE_',
|
||||
confFiles = getConfFiles(),
|
||||
): Promise<
|
||||
{
|
||||
Partial<ApplicationPluginOptions> & {
|
||||
appTitle: string;
|
||||
base: string;
|
||||
port: number;
|
||||
} & Partial<ApplicationPluginOptions>
|
||||
}
|
||||
> {
|
||||
const envConfig = await loadEnv(match, confFiles);
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vben-admin-monorepo",
|
||||
"version": "5.5.2",
|
||||
"version": "5.5.3",
|
||||
"private": true,
|
||||
"keywords": [
|
||||
"monorepo",
|
||||
@@ -99,7 +99,7 @@
|
||||
"node": ">=20.10.0",
|
||||
"pnpm": ">=9.12.0"
|
||||
},
|
||||
"packageManager": "pnpm@9.15.1",
|
||||
"packageManager": "pnpm@9.15.3",
|
||||
"pnpm": {
|
||||
"peerDependencyRules": {
|
||||
"allowedVersions": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/design",
|
||||
"version": "5.5.2",
|
||||
"version": "5.5.3",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -81,3 +81,7 @@
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.z-popup {
|
||||
z-index: var(--popup-z-index);
|
||||
}
|
||||
|
@@ -15,7 +15,11 @@
|
||||
--card-foreground: 210 40% 98%;
|
||||
|
||||
/* Background color for popovers such as <DropdownMenu />, <HoverCard />, <Popover /> */
|
||||
--popover: 222.82deg 8.43% 12.27%;
|
||||
|
||||
/* --popover: 222.82deg 8.43% 12.27%; */
|
||||
|
||||
/* 弹出层的背景色与主题区域背景色太过接近 */
|
||||
--popover: 0 0 14.2%;
|
||||
--popover-foreground: 210 40% 98%;
|
||||
|
||||
/* Muted backgrounds such as <TabsList />, <Skeleton /> and <Switch /> */
|
||||
|
@@ -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';
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/icons",
|
||||
"version": "5.5.2",
|
||||
"version": "5.5.3",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -1,9 +1,7 @@
|
||||
export {
|
||||
ArrowDown,
|
||||
ArrowLeft,
|
||||
ArrowLeftFromLine as MdiMenuOpen,
|
||||
ArrowLeftToLine,
|
||||
ArrowRightFromLine as MdiMenuClose,
|
||||
ArrowRightLeft,
|
||||
ArrowRightToLine,
|
||||
ArrowUp,
|
||||
@@ -29,6 +27,7 @@ export {
|
||||
Github,
|
||||
Grip,
|
||||
GripVertical,
|
||||
Menu as IconDefault,
|
||||
Info,
|
||||
InspectionPanel,
|
||||
Languages,
|
||||
@@ -37,7 +36,8 @@ export {
|
||||
LogOut,
|
||||
MailCheck,
|
||||
Maximize,
|
||||
Menu as IconDefault,
|
||||
ArrowRightFromLine as MdiMenuClose,
|
||||
ArrowLeftFromLine as MdiMenuOpen,
|
||||
Menu,
|
||||
Minimize,
|
||||
Minimize2,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/shared",
|
||||
"version": "5.5.2",
|
||||
"version": "5.5.3",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -45,7 +45,7 @@
|
||||
"default": "./dist/store.mjs"
|
||||
},
|
||||
"./global-state": {
|
||||
"types": "./dist/global-state.d.ts",
|
||||
"types": "./src/global-state.ts",
|
||||
"development": "./src/global-state.ts",
|
||||
"default": "./dist/global-state.mjs"
|
||||
}
|
||||
|
@@ -25,15 +25,6 @@ class StorageManager {
|
||||
: window.sessionStorage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取完整的存储键
|
||||
* @param key 原始键
|
||||
* @returns 带前缀的完整键
|
||||
*/
|
||||
private getFullKey(key: string): string {
|
||||
return `${this.prefix}-${key}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有带前缀的存储项
|
||||
*/
|
||||
@@ -113,6 +104,15 @@ class StorageManager {
|
||||
console.error(`Error setting item with key "${fullKey}":`, error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取完整的存储键
|
||||
* @param key 原始键
|
||||
* @returns 带前缀的完整键
|
||||
*/
|
||||
private getFullKey(key: string): string {
|
||||
return `${this.prefix}-${key}`;
|
||||
}
|
||||
}
|
||||
|
||||
export { StorageManager };
|
||||
|
@@ -56,12 +56,6 @@ describe('bindMethods', () => {
|
||||
|
||||
it('should not bind getter/setter properties', () => {
|
||||
class TestWithGetterSetter {
|
||||
private _value: string = 'test';
|
||||
|
||||
constructor() {
|
||||
bindMethods(this);
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this._value;
|
||||
}
|
||||
@@ -69,6 +63,12 @@ describe('bindMethods', () => {
|
||||
set value(newValue: string) {
|
||||
this._value = newValue;
|
||||
}
|
||||
|
||||
private _value: string = 'test';
|
||||
|
||||
constructor() {
|
||||
bindMethods(this);
|
||||
}
|
||||
}
|
||||
|
||||
const instance = new TestWithGetterSetter();
|
||||
|
@@ -1,4 +1,6 @@
|
||||
import { type ClassValue, clsx } from 'clsx';
|
||||
import type { ClassValue } from 'clsx';
|
||||
|
||||
import { clsx } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
function cn(...inputs: ClassValue[]) {
|
||||
|
@@ -31,6 +31,7 @@ export async function downloadFileFromUrl({
|
||||
|
||||
if (isChrome || isSafari) {
|
||||
triggerDownload(source, resolveFileName(source, fileName));
|
||||
return;
|
||||
}
|
||||
if (!source.includes('?')) {
|
||||
source += '?download';
|
||||
|
@@ -3,12 +3,6 @@ export class StateHandler {
|
||||
private rejectCondition: (() => void) | null = null;
|
||||
private resolveCondition: (() => void) | null = null;
|
||||
|
||||
// 清理 resolve/reject 函数
|
||||
private clearPromises() {
|
||||
this.resolveCondition = null;
|
||||
this.rejectCondition = null;
|
||||
}
|
||||
|
||||
isConditionTrue(): boolean {
|
||||
return this.condition;
|
||||
}
|
||||
@@ -47,4 +41,10 @@ export class StateHandler {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 清理 resolve/reject 函数
|
||||
private clearPromises() {
|
||||
this.resolveCondition = null;
|
||||
this.rejectCondition = null;
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/typings",
|
||||
"version": "5.5.2",
|
||||
"version": "5.5.3",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
2
packages/@core/base/typings/src/app.d.ts
vendored
2
packages/@core/base/typings/src/app.d.ts
vendored
@@ -1,6 +1,8 @@
|
||||
type LayoutType =
|
||||
| 'full-content'
|
||||
| 'header-mixed-nav'
|
||||
| 'header-nav'
|
||||
| 'header-sidebar-nav'
|
||||
| 'mixed-nav'
|
||||
| 'sidebar-mixed-nav'
|
||||
| 'sidebar-nav';
|
||||
|
5
packages/@core/base/typings/src/helper.d.ts
vendored
5
packages/@core/base/typings/src/helper.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
import { type ComputedRef, type MaybeRef } from 'vue';
|
||||
import type { ComputedRef, MaybeRef } from 'vue';
|
||||
|
||||
/**
|
||||
* 深层递归所有属性为可选
|
||||
@@ -109,6 +109,8 @@ type MergeAll<
|
||||
|
||||
type EmitType = (name: Name, ...args: any[]) => void;
|
||||
|
||||
type MaybePromise<T> = Promise<T> | T;
|
||||
|
||||
export type {
|
||||
AnyFunction,
|
||||
AnyNormalFunction,
|
||||
@@ -118,6 +120,7 @@ export type {
|
||||
EmitType,
|
||||
IntervalHandle,
|
||||
MaybeComputedRef,
|
||||
MaybePromise,
|
||||
MaybeReadonlyRef,
|
||||
Merge,
|
||||
MergeAll,
|
||||
|
@@ -1,15 +1,14 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
import type { Component } from 'vue';
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
/**
|
||||
* 扩展路由原始对象
|
||||
*/
|
||||
type ExRouteRecordRaw = {
|
||||
type ExRouteRecordRaw = RouteRecordRaw & {
|
||||
parent?: string;
|
||||
parents?: string[];
|
||||
path?: any;
|
||||
} & RouteRecordRaw;
|
||||
};
|
||||
|
||||
interface MenuRecordBadgeRaw {
|
||||
/**
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user