Explorar o código

chore: 优化 useScrollTo、useWindowSizeFn

vben %!s(int64=2) %!d(string=hai) anos
pai
achega
335f30c887

+ 2 - 0
packages/hooks/src/index.ts

@@ -1,4 +1,6 @@
 export * from './onMountedOrActivated';
 export * from './useAttrs';
 export * from './useRefs';
+export * from './useScrollTo';
+export * from './useWindowSizeFn';
 export { useTimeoutFn } from '@vueuse/core';

+ 3 - 3
packages/hooks/src/useAttrs.ts

@@ -1,7 +1,7 @@
 import { type Recordable } from '@vben/types';
 import { getCurrentInstance, reactive, shallowRef, watchEffect } from 'vue';
 
-interface Options {
+interface UseAttrsOptions {
   excludeListeners?: boolean;
   excludeKeys?: string[];
   excludeDefaultKeys?: boolean;
@@ -14,7 +14,7 @@ function entries<T>(obj: Recordable<T>): [string, T][] {
   return Object.keys(obj).map((key: string) => [key, obj[key]]);
 }
 
-function useAttrs(options: Options = {}): Recordable<any> {
+function useAttrs(options: UseAttrsOptions = {}): Recordable<any> {
   const instance = getCurrentInstance();
   if (!instance) return {};
 
@@ -40,4 +40,4 @@ function useAttrs(options: Options = {}): Recordable<any> {
   return attrs;
 }
 
-export { useAttrs };
+export { useAttrs, type UseAttrsOptions };

+ 10 - 2
packages/hooks/src/useRefs.ts

@@ -1,7 +1,10 @@
 import type { Ref } from 'vue';
 import { onBeforeUpdate, shallowRef } from 'vue';
 
-export function useRefs(): [Ref<HTMLElement[]>, (index: number) => (el: HTMLElement) => void] {
+function useRefs(): {
+  refs: Ref<HTMLElement[]>;
+  setRefs: (index: number) => (el: HTMLElement) => void;
+} {
   const refs = shallowRef([]) as Ref<HTMLElement[]>;
 
   onBeforeUpdate(() => {
@@ -12,5 +15,10 @@ export function useRefs(): [Ref<HTMLElement[]>, (index: number) => (el: HTMLElem
     refs.value[index] = el;
   };
 
-  return [refs, setRefs];
+  return {
+    refs,
+    setRefs,
+  };
 }
+
+export { useRefs };

+ 12 - 11
src/hooks/event/useScrollTo.ts → packages/hooks/src/useScrollTo.ts

@@ -1,35 +1,34 @@
-import { isFunction, isUnDef } from '/@/utils/is';
-import { ref, unref } from 'vue';
+import { shallowRef, unref } from 'vue';
 
-export interface ScrollToParams {
+interface UseScrollToOptions {
   el: any;
   to: number;
   duration?: number;
   callback?: () => any;
 }
 
-const easeInOutQuad = (t: number, b: number, c: number, d: number) => {
+function easeInOutQuad(t: number, b: number, c: number, d: number) {
   t /= d / 2;
   if (t < 1) {
     return (c / 2) * t * t + b;
   }
   t--;
   return (-c / 2) * (t * (t - 2) - 1) + b;
-};
-const move = (el: HTMLElement, amount: number) => {
+}
+
+function move(el: HTMLElement, amount: number) {
   el.scrollTop = amount;
-};
+}
 
 const position = (el: HTMLElement) => {
   return el.scrollTop;
 };
-export function useScrollTo({ el, to, duration = 500, callback }: ScrollToParams) {
-  const isActiveRef = ref(false);
+function useScrollTo({ el, to, duration = 500, callback }: UseScrollToOptions) {
+  const isActiveRef = shallowRef(false);
   const start = position(el);
   const change = to - start;
   const increment = 20;
   let currentTime = 0;
-  duration = isUnDef(duration) ? 500 : duration;
 
   const animateScroll = function () {
     if (!unref(isActiveRef)) {
@@ -41,7 +40,7 @@ export function useScrollTo({ el, to, duration = 500, callback }: ScrollToParams
     if (currentTime < duration && unref(isActiveRef)) {
       requestAnimationFrame(animateScroll);
     } else {
-      if (callback && isFunction(callback)) {
+      if (callback && typeof callback === 'function') {
         callback();
       }
     }
@@ -57,3 +56,5 @@ export function useScrollTo({ el, to, duration = 500, callback }: ScrollToParams
 
   return { start: run, stop };
 }
+
+export { useScrollTo, type UseScrollToOptions };

+ 9 - 4
src/hooks/event/useWindowSizeFn.ts → packages/hooks/src/useWindowSizeFn.ts

@@ -1,12 +1,15 @@
+import { type AnyFunction } from '@vben/types';
 import { tryOnMounted, tryOnUnmounted, useDebounceFn } from '@vueuse/core';
 
-interface WindowSizeOptions {
+interface UseWindowSizeOptions {
+  wait?: number;
   once?: boolean;
   immediate?: boolean;
   listenerOptions?: AddEventListenerOptions | boolean;
 }
 
-export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOptions) {
+function useWindowSizeFn(fn: AnyFunction, options: UseWindowSizeOptions = {}) {
+  const { wait = 150, immediate } = options;
   let handler = () => {
     fn();
   };
@@ -14,7 +17,7 @@ export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOp
   handler = handleSize;
 
   const start = () => {
-    if (options && options.immediate) {
+    if (immediate) {
       handler();
     }
     window.addEventListener('resize', handler);
@@ -31,5 +34,7 @@ export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOp
   tryOnUnmounted(() => {
     stop();
   });
-  return [start, stop];
+  return { start, stop };
 }
+
+export { useWindowSizeFn, type UseWindowSizeOptions };

+ 2 - 2
packages/types/src/utils.ts

@@ -1,12 +1,12 @@
 /**
  * 任意类型的异步函数
  */
-type AnyPromiseFunction = (...arg: any) => PromiseLike<any>;
+type AnyPromiseFunction = (...arg: any[]) => PromiseLike<any>;
 
 /**
  * 任意类型的普通函数
  */
-type AnyNormalFunction = (...arg: any) => any;
+type AnyNormalFunction = (...arg: any[]) => any;
 
 /**
  * 任意类型的函数

+ 1 - 1
src/components/Application/src/search/AppSearchModal.vue

@@ -81,7 +81,7 @@
 
   const { t } = useI18n();
   const { prefixCls } = useDesign('app-search-modal');
-  const [refs, setRefs] = useRefs();
+  const { refs, setRefs } = useRefs();
   const { getIsMobile } = useAppInject();
 
   const { handleSearch, searchResult, keyword, activeIndex, handleEnter, handleMouseenter } =

+ 1 - 1
src/components/Application/src/search/useMenuSearch.ts

@@ -5,7 +5,7 @@ import { getMenus } from '/@/router/menus';
 import { cloneDeep } from 'lodash-es';
 import { filter, forEach } from '/@/utils/helper/treeHelper';
 import { useGo } from '/@/hooks/web/usePage';
-import { useScrollTo } from '/@/hooks/event/useScrollTo';
+import { useScrollTo } from '@vben/hooks';
 import { onKeyStroke, useDebounceFn } from '@vueuse/core';
 import { useI18n } from '/@/hooks/web/useI18n';
 

+ 12 - 2
src/components/CodeEditor/src/codemirror/CodeMirror.vue

@@ -3,10 +3,20 @@
 </template>
 
 <script lang="ts" setup>
-  import { ref, onMounted, onUnmounted, watchEffect, watch, unref, nextTick } from 'vue';
+  import {
+    type PropType,
+    ref,
+    onMounted,
+    onUnmounted,
+    watchEffect,
+    watch,
+    unref,
+    nextTick,
+  } from 'vue';
+  import type { Nullable } from '@vben/types';
+  import { useWindowSizeFn } from '@vben/hooks';
   import { useDebounceFn } from '@vueuse/core';
   import { useAppStore } from '/@/store/modules/app';
-  import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
   import CodeMirror from 'codemirror';
   import { MODE } from './../typing';
   // css

+ 2 - 1
src/components/Container/src/ScrollContainer.vue

@@ -7,7 +7,8 @@
 <script lang="ts">
   import { defineComponent, ref, unref, nextTick } from 'vue';
   import { Scrollbar, ScrollbarType } from '/@/components/Scrollbar';
-  import { useScrollTo } from '/@/hooks/event/useScrollTo';
+  import { useScrollTo } from '@vben/hooks';
+  import { type Nullable } from '@vben/types';
 
   export default defineComponent({
     name: 'ScrollContainer',

+ 7 - 6
src/components/Modal/src/components/ModalWrapper.vue

@@ -18,7 +18,8 @@
     nextTick,
     onUnmounted,
   } from 'vue';
-  import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
+  import { useWindowSizeFn } from '@vben/hooks';
+  import { type AnyFunction } from '@vben/types';
   import { ScrollContainer } from '/@/components/Container';
   import { createModalContext } from '../hooks/useModalContext';
   import { useMutationObserver } from '@vueuse/core';
@@ -43,14 +44,14 @@
     props,
     emits: ['height-change', 'ext-height'],
     setup(props, { emit }) {
-      const wrapperRef = ref<ComponentRef>(null);
-      const spinRef = ref<ElRef>(null);
+      const wrapperRef = ref(null);
+      const spinRef = ref(null);
       const realHeightRef = ref(0);
       const minRealHeightRef = ref(0);
 
       let realHeight = 0;
 
-      let stopElResizeFn: Fn = () => {};
+      let stopElResizeFn: AnyFunction = () => {};
 
       useWindowSizeFn(setModalHeight.bind(null, false));
 
@@ -116,7 +117,7 @@
         const wrapperRefDom = unref(wrapperRef);
         if (!wrapperRefDom) return;
 
-        const bodyDom = wrapperRefDom.$el.parentElement;
+        const bodyDom = (wrapperRefDom as any).$el.parentElement;
         if (!bodyDom) return;
         bodyDom.style.padding = '0';
         await nextTick();
@@ -139,7 +140,7 @@
             maxHeight -= 26;
           }
           await nextTick();
-          const spinEl = unref(spinRef);
+          const spinEl: any = unref(spinRef);
 
           if (!spinEl) return;
           await nextTick();

+ 2 - 3
src/components/Table/src/hooks/useTableScroll.ts

@@ -2,9 +2,8 @@ import type { BasicTableProps, TableRowSelection, BasicColumn } from '../types/t
 import { Ref, ComputedRef, ref, computed, unref, nextTick, watch } from 'vue';
 import { getViewportOffset } from '/@/utils/domUtils';
 import { isBoolean } from '/@/utils/is';
-import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
+import { useWindowSizeFn, onMountedOrActivated } from '@vben/hooks';
 import { useModalContext } from '/@/components/Modal';
-import { onMountedOrActivated } from '@vben/hooks';
 import { useDebounceFn } from '@vueuse/core';
 
 export function useTableScroll(
@@ -171,7 +170,7 @@ export function useTableScroll(
 
     bodyEl!.style.height = `${height}px`;
   }
-  useWindowSizeFn(calcTableHeight, 280);
+  useWindowSizeFn(calcTableHeight, { wait: 280 });
   onMountedOrActivated(() => {
     calcTableHeight();
     nextTick(() => {

+ 0 - 1
src/hooks/core/useContext.ts

@@ -4,7 +4,6 @@ import {
   inject,
   reactive,
   readonly as defineReadonly,
-  // defineComponent,
   UnwrapRef,
 } from 'vue';
 

+ 2 - 4
src/hooks/web/useContentHeight.ts

@@ -1,6 +1,5 @@
 import { ComputedRef, isRef, nextTick, Ref, ref, unref, watch } from 'vue';
-import { onMountedOrActivated } from '@vben/hooks';
-import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
+import { onMountedOrActivated, useWindowSizeFn } from '@vben/hooks';
 import { useLayoutHeight } from '/@/layouts/default/content/useContentViewHeight';
 import { getViewportOffset } from '/@/utils/domUtils';
 import { isNumber, isString } from '/@/utils/is';
@@ -173,8 +172,7 @@ export function useContentHeight(
     () => {
       calcContentHeight();
     },
-    50,
-    { immediate: true },
+    { wait: 50, immediate: true },
   );
   watch(
     () => [layoutFooterHeightRef.value],

+ 0 - 1
src/hooks/web/useTitle.ts

@@ -4,7 +4,6 @@ import { useTitle as usePageTitle } from '@vueuse/core';
 import { useGlobSetting } from '/@/hooks/setting';
 import { useRouter } from 'vue-router';
 import { useLocaleStore } from '/@/store/modules/locale';
-
 import { REDIRECT_NAME } from '/@/router/constant';
 
 /**

+ 2 - 3
src/layouts/default/content/useContentViewHeight.ts

@@ -1,6 +1,6 @@
 import { ref, computed, unref } from 'vue';
 import { createPageContext } from '/@/hooks/component/usePageContext';
-import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
+import { useWindowSizeFn } from '@vben/hooks';
 
 const headerHeightRef = ref(0);
 const footerHeightRef = ref(0);
@@ -26,8 +26,7 @@ export function useContentViewHeight() {
     () => {
       contentHeight.value = window.innerHeight;
     },
-    100,
-    { immediate: true },
+    { wait: 100, immediate: true },
   );
 
   async function setPageHeight(height: number) {

+ 2 - 2
src/views/sys/iframe/index.vue

@@ -14,7 +14,7 @@
   import type { CSSProperties } from 'vue';
   import { ref, unref, computed } from 'vue';
   import { Spin } from 'ant-design-vue';
-  import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
+  import { useWindowSizeFn } from '@vben/hooks';
   import { propTypes } from '/@/utils/propTypes';
   import { useDesign } from '/@/hooks/web/useDesign';
   import { useLayoutHeight } from '/@/layouts/default/content/useContentViewHeight';
@@ -30,7 +30,7 @@
   const { headerHeightRef } = useLayoutHeight();
 
   const { prefixCls } = useDesign('iframe-page');
-  useWindowSizeFn(calcHeight, 150, { immediate: true });
+  useWindowSizeFn(calcHeight, { wait: 150, immediate: true });
 
   const getWrapStyle = computed((): CSSProperties => {
     return {