Commit 335f30c887056387f7b9eee5eb4ab28540424253
1 parent
6a9bd686
chore: 优化 useScrollTo、useWindowSizeFn
Showing
17 changed files
with
69 additions
and
47 deletions
packages/hooks/src/index.ts
packages/hooks/src/useAttrs.ts
1 | 1 | import { type Recordable } from '@vben/types'; |
2 | 2 | import { getCurrentInstance, reactive, shallowRef, watchEffect } from 'vue'; |
3 | 3 | |
4 | -interface Options { | |
4 | +interface UseAttrsOptions { | |
5 | 5 | excludeListeners?: boolean; |
6 | 6 | excludeKeys?: string[]; |
7 | 7 | excludeDefaultKeys?: boolean; |
... | ... | @@ -14,7 +14,7 @@ function entries<T>(obj: Recordable<T>): [string, T][] { |
14 | 14 | return Object.keys(obj).map((key: string) => [key, obj[key]]); |
15 | 15 | } |
16 | 16 | |
17 | -function useAttrs(options: Options = {}): Recordable<any> { | |
17 | +function useAttrs(options: UseAttrsOptions = {}): Recordable<any> { | |
18 | 18 | const instance = getCurrentInstance(); |
19 | 19 | if (!instance) return {}; |
20 | 20 | |
... | ... | @@ -40,4 +40,4 @@ function useAttrs(options: Options = {}): Recordable<any> { |
40 | 40 | return attrs; |
41 | 41 | } |
42 | 42 | |
43 | -export { useAttrs }; | |
43 | +export { useAttrs, type UseAttrsOptions }; | ... | ... |
packages/hooks/src/useRefs.ts
1 | 1 | import type { Ref } from 'vue'; |
2 | 2 | import { onBeforeUpdate, shallowRef } from 'vue'; |
3 | 3 | |
4 | -export function useRefs(): [Ref<HTMLElement[]>, (index: number) => (el: HTMLElement) => void] { | |
4 | +function useRefs(): { | |
5 | + refs: Ref<HTMLElement[]>; | |
6 | + setRefs: (index: number) => (el: HTMLElement) => void; | |
7 | +} { | |
5 | 8 | const refs = shallowRef([]) as Ref<HTMLElement[]>; |
6 | 9 | |
7 | 10 | onBeforeUpdate(() => { |
... | ... | @@ -12,5 +15,10 @@ export function useRefs(): [Ref<HTMLElement[]>, (index: number) => (el: HTMLElem |
12 | 15 | refs.value[index] = el; |
13 | 16 | }; |
14 | 17 | |
15 | - return [refs, setRefs]; | |
18 | + return { | |
19 | + refs, | |
20 | + setRefs, | |
21 | + }; | |
16 | 22 | } |
23 | + | |
24 | +export { useRefs }; | ... | ... |
src/hooks/event/useScrollTo.ts renamed to packages/hooks/src/useScrollTo.ts
1 | -import { isFunction, isUnDef } from '/@/utils/is'; | |
2 | -import { ref, unref } from 'vue'; | |
1 | +import { shallowRef, unref } from 'vue'; | |
3 | 2 | |
4 | -export interface ScrollToParams { | |
3 | +interface UseScrollToOptions { | |
5 | 4 | el: any; |
6 | 5 | to: number; |
7 | 6 | duration?: number; |
8 | 7 | callback?: () => any; |
9 | 8 | } |
10 | 9 | |
11 | -const easeInOutQuad = (t: number, b: number, c: number, d: number) => { | |
10 | +function easeInOutQuad(t: number, b: number, c: number, d: number) { | |
12 | 11 | t /= d / 2; |
13 | 12 | if (t < 1) { |
14 | 13 | return (c / 2) * t * t + b; |
15 | 14 | } |
16 | 15 | t--; |
17 | 16 | return (-c / 2) * (t * (t - 2) - 1) + b; |
18 | -}; | |
19 | -const move = (el: HTMLElement, amount: number) => { | |
17 | +} | |
18 | + | |
19 | +function move(el: HTMLElement, amount: number) { | |
20 | 20 | el.scrollTop = amount; |
21 | -}; | |
21 | +} | |
22 | 22 | |
23 | 23 | const position = (el: HTMLElement) => { |
24 | 24 | return el.scrollTop; |
25 | 25 | }; |
26 | -export function useScrollTo({ el, to, duration = 500, callback }: ScrollToParams) { | |
27 | - const isActiveRef = ref(false); | |
26 | +function useScrollTo({ el, to, duration = 500, callback }: UseScrollToOptions) { | |
27 | + const isActiveRef = shallowRef(false); | |
28 | 28 | const start = position(el); |
29 | 29 | const change = to - start; |
30 | 30 | const increment = 20; |
31 | 31 | let currentTime = 0; |
32 | - duration = isUnDef(duration) ? 500 : duration; | |
33 | 32 | |
34 | 33 | const animateScroll = function () { |
35 | 34 | if (!unref(isActiveRef)) { |
... | ... | @@ -41,7 +40,7 @@ export function useScrollTo({ el, to, duration = 500, callback }: ScrollToParams |
41 | 40 | if (currentTime < duration && unref(isActiveRef)) { |
42 | 41 | requestAnimationFrame(animateScroll); |
43 | 42 | } else { |
44 | - if (callback && isFunction(callback)) { | |
43 | + if (callback && typeof callback === 'function') { | |
45 | 44 | callback(); |
46 | 45 | } |
47 | 46 | } |
... | ... | @@ -57,3 +56,5 @@ export function useScrollTo({ el, to, duration = 500, callback }: ScrollToParams |
57 | 56 | |
58 | 57 | return { start: run, stop }; |
59 | 58 | } |
59 | + | |
60 | +export { useScrollTo, type UseScrollToOptions }; | ... | ... |
src/hooks/event/useWindowSizeFn.ts renamed to packages/hooks/src/useWindowSizeFn.ts
1 | +import { type AnyFunction } from '@vben/types'; | |
1 | 2 | import { tryOnMounted, tryOnUnmounted, useDebounceFn } from '@vueuse/core'; |
2 | 3 | |
3 | -interface WindowSizeOptions { | |
4 | +interface UseWindowSizeOptions { | |
5 | + wait?: number; | |
4 | 6 | once?: boolean; |
5 | 7 | immediate?: boolean; |
6 | 8 | listenerOptions?: AddEventListenerOptions | boolean; |
7 | 9 | } |
8 | 10 | |
9 | -export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOptions) { | |
11 | +function useWindowSizeFn(fn: AnyFunction, options: UseWindowSizeOptions = {}) { | |
12 | + const { wait = 150, immediate } = options; | |
10 | 13 | let handler = () => { |
11 | 14 | fn(); |
12 | 15 | }; |
... | ... | @@ -14,7 +17,7 @@ export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOp |
14 | 17 | handler = handleSize; |
15 | 18 | |
16 | 19 | const start = () => { |
17 | - if (options && options.immediate) { | |
20 | + if (immediate) { | |
18 | 21 | handler(); |
19 | 22 | } |
20 | 23 | window.addEventListener('resize', handler); |
... | ... | @@ -31,5 +34,7 @@ export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOp |
31 | 34 | tryOnUnmounted(() => { |
32 | 35 | stop(); |
33 | 36 | }); |
34 | - return [start, stop]; | |
37 | + return { start, stop }; | |
35 | 38 | } |
39 | + | |
40 | +export { useWindowSizeFn, type UseWindowSizeOptions }; | ... | ... |
packages/types/src/utils.ts
1 | 1 | /** |
2 | 2 | * 任意类型的异步函数 |
3 | 3 | */ |
4 | -type AnyPromiseFunction = (...arg: any) => PromiseLike<any>; | |
4 | +type AnyPromiseFunction = (...arg: any[]) => PromiseLike<any>; | |
5 | 5 | |
6 | 6 | /** |
7 | 7 | * 任意类型的普通函数 |
8 | 8 | */ |
9 | -type AnyNormalFunction = (...arg: any) => any; | |
9 | +type AnyNormalFunction = (...arg: any[]) => any; | |
10 | 10 | |
11 | 11 | /** |
12 | 12 | * 任意类型的函数 | ... | ... |
src/components/Application/src/search/AppSearchModal.vue
... | ... | @@ -81,7 +81,7 @@ |
81 | 81 | |
82 | 82 | const { t } = useI18n(); |
83 | 83 | const { prefixCls } = useDesign('app-search-modal'); |
84 | - const [refs, setRefs] = useRefs(); | |
84 | + const { refs, setRefs } = useRefs(); | |
85 | 85 | const { getIsMobile } = useAppInject(); |
86 | 86 | |
87 | 87 | const { handleSearch, searchResult, keyword, activeIndex, handleEnter, handleMouseenter } = | ... | ... |
src/components/Application/src/search/useMenuSearch.ts
... | ... | @@ -5,7 +5,7 @@ import { getMenus } from '/@/router/menus'; |
5 | 5 | import { cloneDeep } from 'lodash-es'; |
6 | 6 | import { filter, forEach } from '/@/utils/helper/treeHelper'; |
7 | 7 | import { useGo } from '/@/hooks/web/usePage'; |
8 | -import { useScrollTo } from '/@/hooks/event/useScrollTo'; | |
8 | +import { useScrollTo } from '@vben/hooks'; | |
9 | 9 | import { onKeyStroke, useDebounceFn } from '@vueuse/core'; |
10 | 10 | import { useI18n } from '/@/hooks/web/useI18n'; |
11 | 11 | ... | ... |
src/components/CodeEditor/src/codemirror/CodeMirror.vue
... | ... | @@ -3,10 +3,20 @@ |
3 | 3 | </template> |
4 | 4 | |
5 | 5 | <script lang="ts" setup> |
6 | - import { ref, onMounted, onUnmounted, watchEffect, watch, unref, nextTick } from 'vue'; | |
6 | + import { | |
7 | + type PropType, | |
8 | + ref, | |
9 | + onMounted, | |
10 | + onUnmounted, | |
11 | + watchEffect, | |
12 | + watch, | |
13 | + unref, | |
14 | + nextTick, | |
15 | + } from 'vue'; | |
16 | + import type { Nullable } from '@vben/types'; | |
17 | + import { useWindowSizeFn } from '@vben/hooks'; | |
7 | 18 | import { useDebounceFn } from '@vueuse/core'; |
8 | 19 | import { useAppStore } from '/@/store/modules/app'; |
9 | - import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn'; | |
10 | 20 | import CodeMirror from 'codemirror'; |
11 | 21 | import { MODE } from './../typing'; |
12 | 22 | // css | ... | ... |
src/components/Container/src/ScrollContainer.vue
... | ... | @@ -7,7 +7,8 @@ |
7 | 7 | <script lang="ts"> |
8 | 8 | import { defineComponent, ref, unref, nextTick } from 'vue'; |
9 | 9 | import { Scrollbar, ScrollbarType } from '/@/components/Scrollbar'; |
10 | - import { useScrollTo } from '/@/hooks/event/useScrollTo'; | |
10 | + import { useScrollTo } from '@vben/hooks'; | |
11 | + import { type Nullable } from '@vben/types'; | |
11 | 12 | |
12 | 13 | export default defineComponent({ |
13 | 14 | name: 'ScrollContainer', | ... | ... |
src/components/Modal/src/components/ModalWrapper.vue
... | ... | @@ -18,7 +18,8 @@ |
18 | 18 | nextTick, |
19 | 19 | onUnmounted, |
20 | 20 | } from 'vue'; |
21 | - import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn'; | |
21 | + import { useWindowSizeFn } from '@vben/hooks'; | |
22 | + import { type AnyFunction } from '@vben/types'; | |
22 | 23 | import { ScrollContainer } from '/@/components/Container'; |
23 | 24 | import { createModalContext } from '../hooks/useModalContext'; |
24 | 25 | import { useMutationObserver } from '@vueuse/core'; |
... | ... | @@ -43,14 +44,14 @@ |
43 | 44 | props, |
44 | 45 | emits: ['height-change', 'ext-height'], |
45 | 46 | setup(props, { emit }) { |
46 | - const wrapperRef = ref<ComponentRef>(null); | |
47 | - const spinRef = ref<ElRef>(null); | |
47 | + const wrapperRef = ref(null); | |
48 | + const spinRef = ref(null); | |
48 | 49 | const realHeightRef = ref(0); |
49 | 50 | const minRealHeightRef = ref(0); |
50 | 51 | |
51 | 52 | let realHeight = 0; |
52 | 53 | |
53 | - let stopElResizeFn: Fn = () => {}; | |
54 | + let stopElResizeFn: AnyFunction = () => {}; | |
54 | 55 | |
55 | 56 | useWindowSizeFn(setModalHeight.bind(null, false)); |
56 | 57 | |
... | ... | @@ -116,7 +117,7 @@ |
116 | 117 | const wrapperRefDom = unref(wrapperRef); |
117 | 118 | if (!wrapperRefDom) return; |
118 | 119 | |
119 | - const bodyDom = wrapperRefDom.$el.parentElement; | |
120 | + const bodyDom = (wrapperRefDom as any).$el.parentElement; | |
120 | 121 | if (!bodyDom) return; |
121 | 122 | bodyDom.style.padding = '0'; |
122 | 123 | await nextTick(); |
... | ... | @@ -139,7 +140,7 @@ |
139 | 140 | maxHeight -= 26; |
140 | 141 | } |
141 | 142 | await nextTick(); |
142 | - const spinEl = unref(spinRef); | |
143 | + const spinEl: any = unref(spinRef); | |
143 | 144 | |
144 | 145 | if (!spinEl) return; |
145 | 146 | await nextTick(); | ... | ... |
src/components/Table/src/hooks/useTableScroll.ts
... | ... | @@ -2,9 +2,8 @@ import type { BasicTableProps, TableRowSelection, BasicColumn } from '../types/t |
2 | 2 | import { Ref, ComputedRef, ref, computed, unref, nextTick, watch } from 'vue'; |
3 | 3 | import { getViewportOffset } from '/@/utils/domUtils'; |
4 | 4 | import { isBoolean } from '/@/utils/is'; |
5 | -import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn'; | |
5 | +import { useWindowSizeFn, onMountedOrActivated } from '@vben/hooks'; | |
6 | 6 | import { useModalContext } from '/@/components/Modal'; |
7 | -import { onMountedOrActivated } from '@vben/hooks'; | |
8 | 7 | import { useDebounceFn } from '@vueuse/core'; |
9 | 8 | |
10 | 9 | export function useTableScroll( |
... | ... | @@ -171,7 +170,7 @@ export function useTableScroll( |
171 | 170 | |
172 | 171 | bodyEl!.style.height = `${height}px`; |
173 | 172 | } |
174 | - useWindowSizeFn(calcTableHeight, 280); | |
173 | + useWindowSizeFn(calcTableHeight, { wait: 280 }); | |
175 | 174 | onMountedOrActivated(() => { |
176 | 175 | calcTableHeight(); |
177 | 176 | nextTick(() => { | ... | ... |
src/hooks/core/useContext.ts
src/hooks/web/useContentHeight.ts
1 | 1 | import { ComputedRef, isRef, nextTick, Ref, ref, unref, watch } from 'vue'; |
2 | -import { onMountedOrActivated } from '@vben/hooks'; | |
3 | -import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn'; | |
2 | +import { onMountedOrActivated, useWindowSizeFn } from '@vben/hooks'; | |
4 | 3 | import { useLayoutHeight } from '/@/layouts/default/content/useContentViewHeight'; |
5 | 4 | import { getViewportOffset } from '/@/utils/domUtils'; |
6 | 5 | import { isNumber, isString } from '/@/utils/is'; |
... | ... | @@ -173,8 +172,7 @@ export function useContentHeight( |
173 | 172 | () => { |
174 | 173 | calcContentHeight(); |
175 | 174 | }, |
176 | - 50, | |
177 | - { immediate: true }, | |
175 | + { wait: 50, immediate: true }, | |
178 | 176 | ); |
179 | 177 | watch( |
180 | 178 | () => [layoutFooterHeightRef.value], | ... | ... |
src/hooks/web/useTitle.ts
... | ... | @@ -4,7 +4,6 @@ import { useTitle as usePageTitle } from '@vueuse/core'; |
4 | 4 | import { useGlobSetting } from '/@/hooks/setting'; |
5 | 5 | import { useRouter } from 'vue-router'; |
6 | 6 | import { useLocaleStore } from '/@/store/modules/locale'; |
7 | - | |
8 | 7 | import { REDIRECT_NAME } from '/@/router/constant'; |
9 | 8 | |
10 | 9 | /** | ... | ... |
src/layouts/default/content/useContentViewHeight.ts
1 | 1 | import { ref, computed, unref } from 'vue'; |
2 | 2 | import { createPageContext } from '/@/hooks/component/usePageContext'; |
3 | -import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn'; | |
3 | +import { useWindowSizeFn } from '@vben/hooks'; | |
4 | 4 | |
5 | 5 | const headerHeightRef = ref(0); |
6 | 6 | const footerHeightRef = ref(0); |
... | ... | @@ -26,8 +26,7 @@ export function useContentViewHeight() { |
26 | 26 | () => { |
27 | 27 | contentHeight.value = window.innerHeight; |
28 | 28 | }, |
29 | - 100, | |
30 | - { immediate: true }, | |
29 | + { wait: 100, immediate: true }, | |
31 | 30 | ); |
32 | 31 | |
33 | 32 | async function setPageHeight(height: number) { | ... | ... |
src/views/sys/iframe/index.vue
... | ... | @@ -14,7 +14,7 @@ |
14 | 14 | import type { CSSProperties } from 'vue'; |
15 | 15 | import { ref, unref, computed } from 'vue'; |
16 | 16 | import { Spin } from 'ant-design-vue'; |
17 | - import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn'; | |
17 | + import { useWindowSizeFn } from '@vben/hooks'; | |
18 | 18 | import { propTypes } from '/@/utils/propTypes'; |
19 | 19 | import { useDesign } from '/@/hooks/web/useDesign'; |
20 | 20 | import { useLayoutHeight } from '/@/layouts/default/content/useContentViewHeight'; |
... | ... | @@ -30,7 +30,7 @@ |
30 | 30 | const { headerHeightRef } = useLayoutHeight(); |
31 | 31 | |
32 | 32 | const { prefixCls } = useDesign('iframe-page'); |
33 | - useWindowSizeFn(calcHeight, 150, { immediate: true }); | |
33 | + useWindowSizeFn(calcHeight, { wait: 150, immediate: true }); | |
34 | 34 | |
35 | 35 | const getWrapStyle = computed((): CSSProperties => { |
36 | 36 | return { | ... | ... |