Commit 335f30c887056387f7b9eee5eb4ab28540424253

Authored by vben
1 parent 6a9bd686

chore: 优化 useScrollTo、useWindowSizeFn

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