Commit 335f30c887056387f7b9eee5eb4ab28540424253

Authored by vben
1 parent 6a9bd686

chore: 优化 useScrollTo、useWindowSizeFn

packages/hooks/src/index.ts
1 1 export * from './onMountedOrActivated';
2 2 export * from './useAttrs';
3 3 export * from './useRefs';
  4 +export * from './useScrollTo';
  5 +export * from './useWindowSizeFn';
4 6 export { useTimeoutFn } from '@vueuse/core';
... ...
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&lt;any&gt; {
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&lt;HTMLElement[]&gt;, (index: number) =&gt; (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&lt;T&gt;(fn: Fn&lt;T&gt;, 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&lt;T&gt;(fn: Fn&lt;T&gt;, 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 &#39;/@/router/menus&#39;;
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 &#39;../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
... ... @@ -4,7 +4,6 @@ import {
4 4 inject,
5 5 reactive,
6 6 readonly as defineReadonly,
7   - // defineComponent,
8 7 UnwrapRef,
9 8 } from 'vue';
10 9  
... ...
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 &#39;@vueuse/core&#39;;
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 {
... ...