@peng_kai/kit 0.0.15 → 0.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +41 -0
- package/admin/components/filter/index.ts +5 -0
- package/admin/{filter → components/filter/src}/FilterDrawer.vue +12 -9
- package/admin/{filter → components/filter/src}/FilterParam.vue +15 -15
- package/admin/{filter → components/filter/src}/FilterReset.vue +7 -4
- package/admin/{filter → components/filter/src}/useFilterParams.ts +9 -9
- package/admin/{filter → components/filter/src}/useFilterQuery.ts +11 -11
- package/admin/components/scroll-nav/index.ts +1 -1
- package/admin/components/scroll-nav/src/ScrollNav.vue +9 -9
- package/admin/components/text/index.ts +6 -6
- package/admin/components/text/src/Amount.vue +22 -19
- package/admin/components/text/src/Datetime.vue +12 -12
- package/admin/components/text/src/Duration.vue +13 -13
- package/admin/components/text/src/Hash.vue +13 -11
- package/admin/components/text/src/createTagGetter.ts +7 -7
- package/admin/defines/index.ts +4 -5
- package/admin/defines/page/definePage.ts +12 -0
- package/admin/defines/page/index.ts +1 -0
- package/admin/defines/route/defineRoute.ts +14 -0
- package/admin/defines/route/getRoutes.ts +84 -0
- package/admin/defines/route/helpers.ts +49 -0
- package/admin/defines/route/index.ts +73 -0
- package/admin/defines/route-guard/defineRouteGuard.ts +18 -0
- package/admin/defines/route-guard/getRouteGuards.ts +40 -0
- package/admin/defines/route-guard/index.ts +2 -0
- package/admin/defines/startup/defineStartup.ts +11 -0
- package/admin/defines/startup/getStartups.ts +30 -0
- package/admin/defines/startup/index.ts +2 -0
- package/admin/hooks/index.ts +5 -6
- package/admin/hooks/useMenu.ts +48 -48
- package/admin/hooks/usePage.ts +67 -65
- package/admin/hooks/usePageTab.ts +17 -17
- package/admin/layout/large/Breadcrumb.vue +15 -16
- package/admin/layout/large/Content.vue +4 -4
- package/admin/layout/large/Menu.vue +20 -19
- package/admin/layout/large/PageTab.vue +4 -4
- package/admin/layout/large/index.ts +4 -4
- package/admin/permission/index.ts +4 -0
- package/admin/permission/routerGuard.ts +43 -0
- package/admin/permission/usePermission.ts +52 -0
- package/admin/permission/vuePlugin.ts +30 -0
- package/admin/route-guards/index.ts +2 -0
- package/admin/route-guards/pageProgress.ts +16 -0
- package/admin/route-guards/pageTitle.ts +24 -0
- package/admin/types/assist.ts +10 -0
- package/admin/unocss/index.ts +1 -1
- package/antd/components/InputNumberRange.vue +21 -15
- package/antd/directives/formLabelAlign.ts +28 -23
- package/antd/hooks/createAntdModal.ts +29 -29
- package/antd/hooks/useAntdDrawer.ts +31 -31
- package/antd/hooks/useAntdForm.helpers.ts +18 -18
- package/antd/hooks/useAntdForm.ts +38 -37
- package/antd/hooks/useAntdModal.ts +25 -25
- package/antd/hooks/useAntdTable.ts +22 -22
- package/antd/hooks/useAntdTheme.ts +86 -0
- package/antd/index.ts +8 -7
- package/eslint.config.js +50 -0
- package/kitDependencies.ts +21 -7
- package/package.json +22 -16
- package/pnpm-lock.yaml +2147 -56
- package/request/helpers.ts +30 -13
- package/request/index.ts +2 -2
- package/request/interceptors/checkCode.ts +8 -8
- package/request/interceptors/filterEmptyValue.ts +9 -9
- package/request/interceptors/formatPaging.ts +12 -12
- package/request/interceptors/index.ts +7 -6
- package/request/interceptors/popupMessage.ts +35 -35
- package/request/interceptors/returnResultType.ts +19 -19
- package/request/interceptors/toLogin.ts +13 -0
- package/request/interceptors/unitizeAxiosError.ts +7 -7
- package/request/queryClient.ts +42 -0
- package/request/request.ts +21 -21
- package/request/type.d.ts +18 -18
- package/tsconfig.json +41 -12
- package/utils/index.ts +59 -31
- package/vue/components/index.ts +1 -0
- package/{components → vue/components}/infinite-query/index.ts +1 -1
- package/{components → vue/components}/infinite-query/src/InfiniteQuery.vue +29 -29
- package/{components → vue/components}/infinite-query/src/useCreateTrigger.ts +13 -13
- package/vue/hooks/useComponentRef.ts +12 -12
- package/vue/hooks/useIsMounted.ts +4 -4
- package/vue/hooks/useTeleportTarget.ts +7 -7
- package/vue/index.ts +4 -3
- package/admin/defines/definePage.ts +0 -14
- package/admin/defines/defineRoute.helpers.ts +0 -37
- package/admin/defines/defineRoute.ts +0 -161
- package/admin/defines/defineRouteGuard.ts +0 -56
- package/admin/defines/defineStartup.ts +0 -41
- package/admin/filter/index.ts +0 -5
- package/admin/hooks/usePermission.ts +0 -5
package/utils/index.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
export const ENV = {
|
|
2
2
|
get isDev() {
|
|
3
|
-
return (import.meta as any).env.DEV
|
|
3
|
+
return (import.meta as any).env.DEV;
|
|
4
4
|
},
|
|
5
5
|
get isProd() {
|
|
6
|
-
return (import.meta as any).env.PROD
|
|
6
|
+
return (import.meta as any).env.PROD;
|
|
7
7
|
},
|
|
8
8
|
get isStaging() {
|
|
9
|
-
return (import.meta as any).env.MODE === 'staging'
|
|
9
|
+
return (import.meta as any).env.MODE === 'staging';
|
|
10
10
|
},
|
|
11
11
|
get isTest() {
|
|
12
|
-
return this.isDev || this.isStaging
|
|
12
|
+
return this.isDev || this.isStaging;
|
|
13
13
|
},
|
|
14
|
-
}
|
|
14
|
+
};
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* 睡眠
|
|
@@ -19,8 +19,15 @@ export const ENV = {
|
|
|
19
19
|
*/
|
|
20
20
|
export function sleep(dur: number) {
|
|
21
21
|
return new Promise((resolve) => {
|
|
22
|
-
setTimeout(resolve, dur)
|
|
23
|
-
})
|
|
22
|
+
setTimeout(resolve, dur);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 是否有授权 Token
|
|
28
|
+
*/
|
|
29
|
+
export function hasToken() {
|
|
30
|
+
return document.cookie.includes('has_token=1');
|
|
24
31
|
}
|
|
25
32
|
|
|
26
33
|
/**
|
|
@@ -31,17 +38,16 @@ export function sleep(dur: number) {
|
|
|
31
38
|
*/
|
|
32
39
|
export function desensitize(str: string | undefined | null, startChars = 4, endChars?: number) {
|
|
33
40
|
if (!str)
|
|
34
|
-
return ''
|
|
41
|
+
return '';
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
endChars ??= startChars
|
|
43
|
+
endChars ??= startChars;
|
|
38
44
|
|
|
39
45
|
if (startChars + endChars >= str.length)
|
|
40
|
-
return str
|
|
46
|
+
return str;
|
|
41
47
|
|
|
42
|
-
const truncatedStr = `${str.substring(0, startChars)}...${str.substring(str.length - endChars)}
|
|
48
|
+
const truncatedStr = `${str.substring(0, startChars)}...${str.substring(str.length - endChars)}`;
|
|
43
49
|
|
|
44
|
-
return truncatedStr
|
|
50
|
+
return truncatedStr;
|
|
45
51
|
}
|
|
46
52
|
|
|
47
53
|
/**
|
|
@@ -51,23 +57,37 @@ export function desensitize(str: string | undefined | null, startChars = 4, endC
|
|
|
51
57
|
* @param type 哈希类型
|
|
52
58
|
*/
|
|
53
59
|
export function getScanBrowser(chain: string, hash: string, type: 'transaction' | 'address' = 'transaction') {
|
|
54
|
-
|
|
55
|
-
const evmType = type === 'transaction' ? 'tx' : type
|
|
60
|
+
type TypeMap = Partial<Record<typeof type, string>>;
|
|
56
61
|
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
const _chain = chain.toUpperCase();
|
|
63
|
+
const evmType = () => type === 'transaction' ? 'tx' : type;
|
|
64
|
+
const urlFn = {
|
|
65
|
+
TRON: () => `https://tronscan.org/#/${type}/${hash}`,
|
|
66
|
+
ETH: () => `https://etherscan.io/${evmType()}/${hash}`,
|
|
67
|
+
ETHEREUM: () => `https://etherscan.io/${evmType()}/${hash}`,
|
|
68
|
+
BSC: () => `https://bscscan.com/${evmType()}/${hash}`,
|
|
69
|
+
BINANCE: () => `https://bscscan.com/${evmType()}/${hash}`,
|
|
70
|
+
BASE: () => `https://basescan.org/${evmType()}/${hash}`,
|
|
71
|
+
HECO: () => `https://hecoscan.io/#/${evmType}/${hash}`,
|
|
72
|
+
POLYGON: () => `https://polygonscan.com/${evmType()}/${hash}`,
|
|
73
|
+
OKEXCHAIN: () => `https://www.okx.com/cn/explorer/oktc/${evmType()}/${hash}`,
|
|
74
|
+
OPBNB: () => `https://opbnbscan.com/${evmType()}/${hash}`,
|
|
75
|
+
APOTS: () => {
|
|
76
|
+
const _type = (<TypeMap>{ transaction: 'txn', address: 'account' })[type] ?? type;
|
|
77
|
+
return `https://explorer.aptoslabs.com/${_type}/${hash}`;
|
|
78
|
+
},
|
|
79
|
+
ARBITRUM: () => `https://arbiscan.io/${evmType()}/${hash}`,
|
|
80
|
+
AVALANCHE: () => `https://subnets.avax.network/c-chain/${evmType()}/${hash}`,
|
|
81
|
+
FANTOM: () => `https://ftmscan.com/${evmType()}/${hash}`,
|
|
82
|
+
OPTIMISM: () => `https://optimistic.etherscan.io/${evmType()}/${hash}`,
|
|
83
|
+
SUI: () => {
|
|
84
|
+
const _type = (<TypeMap>{ transaction: 'txblock' })[type] ?? type;
|
|
85
|
+
return `https://suiexplorer.com/${_type}/${hash}`;
|
|
86
|
+
},
|
|
87
|
+
ZKSYNC: () => `https://explorer.zksync.io/${evmType()}/${hash}`,
|
|
88
|
+
}[_chain] ?? (() => '');
|
|
69
89
|
|
|
70
|
-
return
|
|
90
|
+
return urlFn();
|
|
71
91
|
}
|
|
72
92
|
|
|
73
93
|
/**
|
|
@@ -75,7 +95,7 @@ export function getScanBrowser(chain: string, hash: string, type: 'transaction'
|
|
|
75
95
|
* @param link 链接
|
|
76
96
|
*/
|
|
77
97
|
export function getTelegramBrowser(link: string) {
|
|
78
|
-
return `https://t.me/${link}
|
|
98
|
+
return `https://t.me/${link}`;
|
|
79
99
|
}
|
|
80
100
|
|
|
81
101
|
/**
|
|
@@ -83,7 +103,15 @@ export function getTelegramBrowser(link: string) {
|
|
|
83
103
|
* @param key 查询参数的 Key
|
|
84
104
|
*/
|
|
85
105
|
export function removeUrlSearchParam(key: string) {
|
|
86
|
-
|
|
106
|
+
const url = new URL(window.location.href);
|
|
87
107
|
url.searchParams.delete(key);
|
|
88
108
|
window.history.replaceState({}, '', url);
|
|
89
|
-
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function createSelfKeyProxy<T extends object>() {
|
|
112
|
+
return new Proxy({} as T, {
|
|
113
|
+
get(_, p) {
|
|
114
|
+
return p;
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { InfiniteQuery } from './infinite-query';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default as InfiniteQuery } from './src/InfiniteQuery.vue'
|
|
1
|
+
export { default as InfiniteQuery } from './src/InfiniteQuery.vue';
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { computed, ref, unref } from
|
|
3
|
-
import type { UseInfiniteQueryReturnType } from '@tanstack/vue-query'
|
|
4
|
-
import { useCreateTrigger } from './useCreateTrigger'
|
|
2
|
+
import { computed, ref, unref } from 'vue';
|
|
3
|
+
import type { UseInfiniteQueryReturnType } from '@tanstack/vue-query';
|
|
4
|
+
import { useCreateTrigger } from './useCreateTrigger';
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<script setup lang="ts" generic="T extends UseInfiniteQueryReturnType<any, any>">
|
|
8
|
-
type TPage = T extends UseInfiniteQueryReturnType<infer P, any> ? NonNullable<P> : any
|
|
9
|
-
type TRecord = TPage extends { list: Array<infer I> } ? I : any
|
|
8
|
+
type TPage = T extends UseInfiniteQueryReturnType<infer P, any> ? NonNullable<P> : any;
|
|
9
|
+
type TRecord = TPage extends { list: Array<infer I> } ? I : any;
|
|
10
10
|
|
|
11
11
|
const props = defineProps<{
|
|
12
12
|
queryier: T
|
|
13
|
-
}>()
|
|
13
|
+
}>();
|
|
14
14
|
|
|
15
|
-
const { queryier } = props
|
|
16
|
-
const pages = computed(() => queryier.data.value?.pages)
|
|
15
|
+
const { queryier } = props;
|
|
16
|
+
const pages = computed(() => queryier.data.value?.pages);
|
|
17
17
|
// TODO: 状态之间的互斥仍有问题
|
|
18
|
-
const isInitialLoading = computed(() => queryier.isInitialLoading.value)
|
|
19
|
-
const isInitialLoadingError = computed(() => queryier.isLoadingError.value && !isInitialLoading.value)
|
|
18
|
+
const isInitialLoading = computed(() => queryier.isInitialLoading.value);
|
|
19
|
+
const isInitialLoadingError = computed(() => queryier.isLoadingError.value && !isInitialLoading.value);
|
|
20
20
|
const isMoreLoading = computed(
|
|
21
21
|
() => (queryier.isFetchingNextPage.value || queryier.isFetching.value) && !isInitialLoading.value,
|
|
22
|
-
)
|
|
23
|
-
const isMoreLoadingError = computed(() => queryier.isRefetchError.value && !isMoreLoading.value)
|
|
22
|
+
);
|
|
23
|
+
const isMoreLoadingError = computed(() => queryier.isRefetchError.value && !isMoreLoading.value);
|
|
24
24
|
const noMore = computed(
|
|
25
25
|
() =>
|
|
26
26
|
!queryier.hasNextPage?.value
|
|
@@ -28,51 +28,51 @@ const noMore = computed(
|
|
|
28
28
|
&& !isInitialLoadingError.value
|
|
29
29
|
&& !isMoreLoading.value
|
|
30
30
|
&& !isMoreLoadingError.value,
|
|
31
|
-
)
|
|
32
|
-
const $container = ref<HTMLElement>()
|
|
31
|
+
);
|
|
32
|
+
const $container = ref<HTMLElement>();
|
|
33
33
|
const containerCssVars = computed(() => {
|
|
34
|
-
const ctnEle = unref($container)
|
|
34
|
+
const ctnEle = unref($container);
|
|
35
35
|
|
|
36
36
|
if (!ctnEle)
|
|
37
|
-
return {}
|
|
37
|
+
return {};
|
|
38
38
|
|
|
39
|
-
const rect = ctnEle.getBoundingClientRect()
|
|
39
|
+
const rect = ctnEle.getBoundingClientRect();
|
|
40
40
|
|
|
41
41
|
return {
|
|
42
42
|
'--ctn-height': `${rect.height}px`,
|
|
43
|
-
}
|
|
44
|
-
})
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
45
|
|
|
46
46
|
function refetch() {
|
|
47
|
-
queryier.refetch()
|
|
47
|
+
queryier.refetch();
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
function refetchLastPage() {
|
|
51
51
|
queryier.refetch({
|
|
52
52
|
refetchPage(lastPage: any, _index, allPages: any[]) {
|
|
53
|
-
const lastIndex = allPages?.length - 1
|
|
54
|
-
return lastPage?.pagination?.page === allPages?.[lastIndex]?.pagination?.page
|
|
53
|
+
const lastIndex = allPages?.length - 1;
|
|
54
|
+
return lastPage?.pagination?.page === allPages?.[lastIndex]?.pagination?.page;
|
|
55
55
|
},
|
|
56
|
-
})
|
|
56
|
+
});
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
function fetchNextPage() {
|
|
60
|
-
const { isFetching, isLoading, hasNextPage } = queryier
|
|
60
|
+
const { isFetching, isLoading, hasNextPage } = queryier;
|
|
61
61
|
|
|
62
62
|
if (isFetching.value || isLoading.value || !hasNextPage?.value)
|
|
63
|
-
return
|
|
63
|
+
return;
|
|
64
64
|
|
|
65
|
-
queryier.fetchNextPage()
|
|
65
|
+
queryier.fetchNextPage();
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
function triggerFetchNextPage() {
|
|
69
69
|
if (queryier.isError.value)
|
|
70
|
-
return
|
|
70
|
+
return;
|
|
71
71
|
|
|
72
|
-
fetchNextPage()
|
|
72
|
+
fetchNextPage();
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
useCreateTrigger($container, triggerFetchNextPage)
|
|
75
|
+
useCreateTrigger($container, triggerFetchNextPage);
|
|
76
76
|
</script>
|
|
77
77
|
|
|
78
78
|
<template>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type { Ref } from
|
|
3
|
-
import { useIntersectionObserver, useIntervalFn } from '@vueuse/core'
|
|
1
|
+
import { watch } from 'vue';
|
|
2
|
+
import type { Ref } from 'vue';
|
|
3
|
+
import { useIntersectionObserver, useIntervalFn } from '@vueuse/core';
|
|
4
4
|
|
|
5
5
|
export function useCreateTrigger(containerEle: Ref<HTMLElement | undefined>, callback: Function) {
|
|
6
|
-
const triggerEl = document.createElement('div')
|
|
6
|
+
const triggerEl = document.createElement('div');
|
|
7
7
|
|
|
8
8
|
Object.assign(triggerEl.style, {
|
|
9
9
|
position: 'relative',
|
|
@@ -13,23 +13,23 @@ export function useCreateTrigger(containerEle: Ref<HTMLElement | undefined>, cal
|
|
|
13
13
|
width: '5px',
|
|
14
14
|
height: '5px',
|
|
15
15
|
// background: 'red',
|
|
16
|
-
} satisfies Partial<CSSStyleDeclaration>)
|
|
16
|
+
} satisfies Partial<CSSStyleDeclaration>);
|
|
17
17
|
|
|
18
18
|
useIntervalFn(() => {
|
|
19
|
-
const { transform } = triggerEl.style
|
|
19
|
+
const { transform } = triggerEl.style;
|
|
20
20
|
|
|
21
21
|
if (transform)
|
|
22
|
-
triggerEl.style.removeProperty('transform')
|
|
23
|
-
else triggerEl.style.setProperty('transform', 'translateX(-200%)')
|
|
24
|
-
}, 500)
|
|
22
|
+
triggerEl.style.removeProperty('transform');
|
|
23
|
+
else triggerEl.style.setProperty('transform', 'translateX(-200%)');
|
|
24
|
+
}, 500);
|
|
25
25
|
|
|
26
26
|
useIntersectionObserver(triggerEl, ([entry]) => {
|
|
27
27
|
if (entry.isIntersecting)
|
|
28
|
-
callback()
|
|
29
|
-
})
|
|
28
|
+
callback();
|
|
29
|
+
});
|
|
30
30
|
|
|
31
31
|
watch(containerEle, (ele) => {
|
|
32
32
|
if (ele)
|
|
33
|
-
ele.append(triggerEl)
|
|
34
|
-
})
|
|
33
|
+
ele.append(triggerEl);
|
|
34
|
+
});
|
|
35
35
|
}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { ref } from
|
|
2
|
-
import type { Component } from 'vue'
|
|
3
|
-
import type { ComponentExposed } from 'vue-component-type-helpers'
|
|
1
|
+
import { ref } from 'vue';
|
|
2
|
+
import type { Component } from 'vue';
|
|
3
|
+
import type { ComponentExposed } from 'vue-component-type-helpers';
|
|
4
4
|
|
|
5
5
|
export function useComponentRef<C extends Component>(_component: C) {
|
|
6
|
-
const _cpt = ref<any>()
|
|
6
|
+
const _cpt = ref<any>();
|
|
7
7
|
const refFn = (cpt: any) => {
|
|
8
|
-
_cpt.value = cpt
|
|
9
|
-
}
|
|
8
|
+
_cpt.value = cpt;
|
|
9
|
+
};
|
|
10
10
|
|
|
11
|
-
type Exposed = typeof refFn & Partial<ComponentExposed<C
|
|
11
|
+
type Exposed = typeof refFn & Partial<ComponentExposed<C>>;
|
|
12
12
|
|
|
13
13
|
return new Proxy(refFn as Exposed, {
|
|
14
14
|
get(_target, p) {
|
|
15
15
|
if (!_cpt.value)
|
|
16
|
-
return
|
|
16
|
+
return;
|
|
17
17
|
|
|
18
|
-
return Reflect.get(_cpt.value, p)
|
|
18
|
+
return Reflect.get(_cpt.value, p);
|
|
19
19
|
},
|
|
20
20
|
set(_target, p, newValue) {
|
|
21
21
|
if (!_cpt.value)
|
|
22
|
-
return false
|
|
22
|
+
return false;
|
|
23
23
|
|
|
24
|
-
return Reflect.set(_cpt.value, p, newValue)
|
|
24
|
+
return Reflect.set(_cpt.value, p, newValue);
|
|
25
25
|
},
|
|
26
|
-
})
|
|
26
|
+
});
|
|
27
27
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { onMounted, ref } from 'vue';
|
|
2
2
|
|
|
3
3
|
export function useIsMounted() {
|
|
4
|
-
const mounted = ref(false)
|
|
4
|
+
const mounted = ref(false);
|
|
5
5
|
|
|
6
|
-
onMounted(() => (mounted.value = true))
|
|
6
|
+
onMounted(() => (mounted.value = true));
|
|
7
7
|
|
|
8
|
-
return mounted
|
|
8
|
+
return mounted;
|
|
9
9
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { onMounted, ref } from 'vue';
|
|
2
2
|
|
|
3
3
|
export function useTeleportTarget(selectors: string) {
|
|
4
|
-
const target = ref<HTMLElement | null>()
|
|
4
|
+
const target = ref<HTMLElement | null>();
|
|
5
5
|
|
|
6
6
|
onMounted(() => {
|
|
7
7
|
setTimeout(() => {
|
|
8
|
-
target.value = document.querySelector<HTMLElement>(selectors)
|
|
9
|
-
})
|
|
10
|
-
})
|
|
8
|
+
target.value = document.querySelector<HTMLElement>(selectors);
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
11
|
|
|
12
|
-
return target
|
|
13
|
-
}
|
|
12
|
+
return target;
|
|
13
|
+
}
|
package/vue/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { useComponentRef } from './hooks/useComponentRef'
|
|
2
|
-
export { useTeleportTarget } from './hooks/useTeleportTarget'
|
|
3
|
-
export { useIsMounted } from './hooks/useIsMounted'
|
|
1
|
+
export { useComponentRef } from './hooks/useComponentRef';
|
|
2
|
+
export { useTeleportTarget } from './hooks/useTeleportTarget';
|
|
3
|
+
export { useIsMounted } from './hooks/useIsMounted';
|
|
4
|
+
export { InfiniteQuery } from './components/infinite-query';
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { defineComponent, defineAsyncComponent, h } from 'vue'
|
|
2
|
-
import type { AsyncComponentLoader } from 'vue'
|
|
3
|
-
|
|
4
|
-
export { definePage }
|
|
5
|
-
|
|
6
|
-
function definePage(loader: AsyncComponentLoader) {
|
|
7
|
-
return defineComponent({
|
|
8
|
-
setup() {
|
|
9
|
-
const Page = defineAsyncComponent(loader)
|
|
10
|
-
|
|
11
|
-
return () => h(Page, null)
|
|
12
|
-
},
|
|
13
|
-
})
|
|
14
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { RouteLocationNormalizedLoaded, Router } from 'vue-router'
|
|
2
|
-
|
|
3
|
-
export function getTitle(route?: Pick<RouteLocationNormalizedLoaded, 'meta'>) {
|
|
4
|
-
const mTitle = route?.meta?.title
|
|
5
|
-
|
|
6
|
-
return typeof mTitle === 'function' ? mTitle() : mTitle
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function getMenusByRouter(router: Router) {
|
|
10
|
-
const menuOrderRE = /^(?<key>\w*)@(?<order>\d+)$/
|
|
11
|
-
const routes = router.getRoutes()
|
|
12
|
-
const menus = routes
|
|
13
|
-
.filter(route => menuOrderRE.test((route.meta.menuOrder ?? '')))
|
|
14
|
-
.map((route) => {
|
|
15
|
-
const res = route.meta!.menuOrder!.match(menuOrderRE)
|
|
16
|
-
const parentKey = res?.groups?.key
|
|
17
|
-
const order = Number(res?.groups?.order)
|
|
18
|
-
const name = route.name as string
|
|
19
|
-
const menu = {
|
|
20
|
-
key: name,
|
|
21
|
-
label: route.meta.title ?? name,
|
|
22
|
-
icon: route.meta.icon,
|
|
23
|
-
trigger: () => router.push({ name }),
|
|
24
|
-
order,
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return { parentKey, menu }
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
// 将含有子菜单的菜单的 trigger 设置为空函数
|
|
31
|
-
const hasSubMenus = menus.filter(menu => menus.some(m => m.parentKey === menu.menu.key))
|
|
32
|
-
hasSubMenus.forEach((menu) => {
|
|
33
|
-
menu.menu.trigger = (() => {}) as any
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
return menus
|
|
37
|
-
}
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import type { RouteRecordRaw } from 'vue-router'
|
|
2
|
-
import merge from 'lodash-es/merge'
|
|
3
|
-
import type { VNode } from 'vue'
|
|
4
|
-
import { definePage } from './definePage'
|
|
5
|
-
import { ENV } from "../../utils";
|
|
6
|
-
|
|
7
|
-
export { defineRoute, getRoutes }
|
|
8
|
-
|
|
9
|
-
const RouteSymbol = Symbol('app-route')
|
|
10
|
-
|
|
11
|
-
/** 定义路由 */
|
|
12
|
-
function defineRoute(route: (params: { definePage: typeof definePage }) => RouteRecordRaw[]) {
|
|
13
|
-
const routeFn: any = () => route({ definePage })
|
|
14
|
-
routeFn[RouteSymbol] = true
|
|
15
|
-
|
|
16
|
-
return routeFn
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/** 获取路由 */
|
|
20
|
-
async function getRoutes() {
|
|
21
|
-
const routeFileRE = /\/([A-Za-z0-9-]+.)?route\.ts$/
|
|
22
|
-
const routeFiles = Object.fromEntries(
|
|
23
|
-
Object.entries(getRoutes.modules).filter(([n]) => routeFileRE.test(n)),
|
|
24
|
-
) as Record<string, Function>
|
|
25
|
-
let routes: RouteRecordRaw[] = []
|
|
26
|
-
|
|
27
|
-
for (const name in routeFiles) {
|
|
28
|
-
const module: any = await routeFiles[name]()
|
|
29
|
-
|
|
30
|
-
if (Object.hasOwn(module?.default ?? {}, RouteSymbol))
|
|
31
|
-
Array.prototype.push.apply(routes, module.default())
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// 处理路由
|
|
35
|
-
routes = meregeDefaultRouteParams(routes)
|
|
36
|
-
routes = sortRoute(routes)
|
|
37
|
-
|
|
38
|
-
// 输出路由
|
|
39
|
-
if (!ENV.isProd) {
|
|
40
|
-
console.groupCollapsed('一级路由')
|
|
41
|
-
|
|
42
|
-
console.table(
|
|
43
|
-
routes.map(route => ({ order: route.meta?.order, ...route })),
|
|
44
|
-
['order', 'name', 'path'],
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
console.groupEnd()
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return routes
|
|
51
|
-
}
|
|
52
|
-
getRoutes.modules = {} as any
|
|
53
|
-
|
|
54
|
-
/** 给路由填充默认参数 */
|
|
55
|
-
const defaultRouteParams: Partial<RouteRecordRaw> = {
|
|
56
|
-
meta: {
|
|
57
|
-
title: '标题',
|
|
58
|
-
icon: undefined,
|
|
59
|
-
order: 10,
|
|
60
|
-
requireAuth: true,
|
|
61
|
-
keepAlive: false,
|
|
62
|
-
hiddenTab: false,
|
|
63
|
-
pageKeyFn: route => route.path,
|
|
64
|
-
},
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function meregeDefaultRouteParams(routes: RouteRecordRaw[], parentRoute?: RouteRecordRaw) {
|
|
68
|
-
const _routes: typeof routes = []
|
|
69
|
-
|
|
70
|
-
for (const route of routes) {
|
|
71
|
-
if (route.children?.length)
|
|
72
|
-
route.children = meregeDefaultRouteParams(route.children, route)
|
|
73
|
-
|
|
74
|
-
const newRoute = merge({}, defaultRouteParams, route)
|
|
75
|
-
const { menuOrder } = newRoute.meta!
|
|
76
|
-
|
|
77
|
-
// 处理 menuOrder
|
|
78
|
-
if (typeof menuOrder === 'string')
|
|
79
|
-
newRoute.meta!.menuOrder = menuOrder.replace('..', (parentRoute?.name ?? '') as string)
|
|
80
|
-
|
|
81
|
-
_routes.push(newRoute)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return _routes
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/** 给路由排序 */
|
|
88
|
-
function sortRoute(routes: RouteRecordRaw[]) {
|
|
89
|
-
const _routes = routes.sort((r1, r2) => r1!.meta!.order! - r2!.meta!.order!)
|
|
90
|
-
|
|
91
|
-
for (const route of _routes) {
|
|
92
|
-
if (route.children?.length)
|
|
93
|
-
route.children = sortRoute(route.children)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return _routes
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
declare module 'vue-router' {
|
|
100
|
-
interface RouteMeta {
|
|
101
|
-
/**
|
|
102
|
-
* 路由标题
|
|
103
|
-
*
|
|
104
|
-
* @description 可用来作 document.title 和菜单的名称
|
|
105
|
-
*
|
|
106
|
-
* 默认:APP 名称
|
|
107
|
-
*/
|
|
108
|
-
title?: string | (() => string)
|
|
109
|
-
/**
|
|
110
|
-
* 菜单和面包屑对应的图标
|
|
111
|
-
*
|
|
112
|
-
* 默认:`''`
|
|
113
|
-
*/
|
|
114
|
-
icon?: (() => VNode)
|
|
115
|
-
/**
|
|
116
|
-
* 路由添加顺序,仅作用于一级路由
|
|
117
|
-
*
|
|
118
|
-
* 默认:`10`
|
|
119
|
-
*/
|
|
120
|
-
order?: number
|
|
121
|
-
/**
|
|
122
|
-
* 是否需要登录
|
|
123
|
-
*
|
|
124
|
-
* 默认:`false`
|
|
125
|
-
*/
|
|
126
|
-
requireAuth?: boolean
|
|
127
|
-
/**
|
|
128
|
-
* 缓存页面
|
|
129
|
-
*
|
|
130
|
-
* 默认:`true`
|
|
131
|
-
*/
|
|
132
|
-
keepAlive?: boolean
|
|
133
|
-
/**
|
|
134
|
-
* 菜单排序(升序)
|
|
135
|
-
*
|
|
136
|
-
* 格式:[parent]@[order]
|
|
137
|
-
* - `parent`:可选。不填则默认取路由的 name 值,并在作为一级菜单显示
|
|
138
|
-
* - `order`:必选。路由排序,值越小排越前
|
|
139
|
-
*
|
|
140
|
-
* 例子:
|
|
141
|
-
* - `@10`:一级菜单
|
|
142
|
-
* - `..@10`:所在的路由层级的父级菜单,例如父级菜单是 admin,那么`..`就是`admin`
|
|
143
|
-
* - `admin@10`:指定菜单的父级为 `admin`
|
|
144
|
-
*
|
|
145
|
-
* 默认:undefined。不在菜单中显示
|
|
146
|
-
*/
|
|
147
|
-
menuOrder?: string
|
|
148
|
-
/**
|
|
149
|
-
* 是否隐藏标签页
|
|
150
|
-
*
|
|
151
|
-
* 默认:`false`
|
|
152
|
-
*/
|
|
153
|
-
hiddenTab?: boolean
|
|
154
|
-
/**
|
|
155
|
-
* 用于生成页面运行时的 key
|
|
156
|
-
*
|
|
157
|
-
* 默认:取 route 对象中 path 值
|
|
158
|
-
*/
|
|
159
|
-
pageKeyFn?: (route: RouteLocationNormalizedLoaded) => string
|
|
160
|
-
}
|
|
161
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import type { Router } from 'vue-router'
|
|
2
|
-
import { ENV } from "../../utils";
|
|
3
|
-
|
|
4
|
-
export { defineRouteGuard, getRouteGuards }
|
|
5
|
-
|
|
6
|
-
interface IGuardConfig {
|
|
7
|
-
/** 路由守卫添加顺序(升序加载) */
|
|
8
|
-
order?: number
|
|
9
|
-
setup: (router: Router) => void
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// 路由守卫标识
|
|
13
|
-
const RouteGuardSymbol = Symbol('app-route-guard')
|
|
14
|
-
|
|
15
|
-
// 定义路由守卫
|
|
16
|
-
function defineRouteGuard(guard: IGuardConfig) {
|
|
17
|
-
(guard as any)[RouteGuardSymbol] = true
|
|
18
|
-
guard.order ??= 10
|
|
19
|
-
|
|
20
|
-
return guard
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// 获取路由守卫
|
|
24
|
-
async function getRouteGuards() {
|
|
25
|
-
const routeGuardFileRE = /\/([A-Za-z0-9-]+.)?route-guard\.ts$/
|
|
26
|
-
const routeGuardFiles = Object.fromEntries(
|
|
27
|
-
Object.entries(getRouteGuards.modules).filter(([n]) => routeGuardFileRE.test(n)),
|
|
28
|
-
) as Record<string, Function>
|
|
29
|
-
let routeGuards: Array<IGuardConfig> = []
|
|
30
|
-
let routeGuardRecord: { file: string; order: number }[] = []
|
|
31
|
-
|
|
32
|
-
for (const name in routeGuardFiles) {
|
|
33
|
-
const module: any = await routeGuardFiles[name]()
|
|
34
|
-
|
|
35
|
-
if (Object.hasOwn(module?.default ?? {}, RouteGuardSymbol)) {
|
|
36
|
-
const guard = module.default
|
|
37
|
-
|
|
38
|
-
routeGuards.push(guard)
|
|
39
|
-
routeGuardRecord.push({ file: name, order: guard.order })
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// 处理路由守卫
|
|
44
|
-
routeGuards = routeGuards.sort()
|
|
45
|
-
routeGuardRecord = routeGuardRecord.sort()
|
|
46
|
-
|
|
47
|
-
// 输出路由守卫
|
|
48
|
-
if (!ENV.isProd) {
|
|
49
|
-
console.groupCollapsed('路由守卫')
|
|
50
|
-
console.table(routeGuardRecord, ['order', 'file'])
|
|
51
|
-
console.groupEnd()
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return routeGuards
|
|
55
|
-
}
|
|
56
|
-
getRouteGuards.modules = {} as any
|