Commit d9b19600304227a8471ac9aac65af31aa1b8e113

Authored by vben
1 parent ecfb702b

refactor(hooks): introduce vueuse, delete duplicate hooks

Showing 47 changed files with 128 additions and 603 deletions
CHANGELOG.zh_CN.md
1 1 ## Wip
2 2  
  3 +### ✨ Refactor
  4 +
  5 +- 重构 hook,引入 `@vueuse`,删除其中已有的`hook`,优化现有的 hook
  6 +- `useEvent` 更名->`useEventListener`
  7 +
3 8 ### ✨ Features
4 9  
5 10 - 表单项的`componentsProps`支持函数类型
... ... @@ -16,6 +21,7 @@
16 21 - 修复多个富文本编辑器只显示一个
17 22 - 修复登录过期后重新登录未跳转原来页面的
18 23 - 修复 window 系统动态引入错误
  24 +- 修复页面类型错误
19 25  
20 26 ## 2.0.0-rc.9 (2020-11-9)
21 27  
... ...
package.json
... ... @@ -22,6 +22,7 @@
22 22 },
23 23 "dependencies": {
24 24 "@iconify/iconify": "^2.0.0-rc.2",
  25 + "@vueuse/core": "^4.0.0-beta.40",
25 26 "ant-design-vue": "^2.0.0-beta.15",
26 27 "apexcharts": "3.22.0",
27 28 "axios": "^0.21.0",
... ...
src/App.vue
... ... @@ -13,7 +13,7 @@
13 13 import moment from 'moment';
14 14 import 'moment/dist/locale/zh-cn';
15 15  
16   - import { useConfigProvider, useInitAppConfigStore, useListenerNetWork } from './useApp';
  16 + import { useConfigProvider, useInitAppConfigStore } from './useApp';
17 17 import { useLockPage } from '/@/hooks/web/useLockPage';
18 18 import { useSetting } from '/@/hooks/core/useSetting';
19 19  
... ... @@ -25,8 +25,6 @@
25 25 setup() {
26 26 // Initialize application settings
27 27 useInitAppConfigStore();
28   - // Initialize network monitoring
29   - useListenerNetWork();
30 28 // Initialize breakpoint monitoring
31 29 createBreakpointListen();
32 30 // Get system configuration
... ...
src/components/Breadcrumb/BreadcrumbItem.vue
... ... @@ -11,7 +11,7 @@
11 11 <script lang="ts">
12 12 import { defineComponent, inject, ref, onMounted, unref } from 'vue';
13 13 import { useRouter } from 'vue-router';
14   - import { useEvent } from '/@/hooks/event/useEvent';
  14 + import { useEventListener } from '/@/hooks/event/useEventListener';
15 15  
16 16 export default defineComponent({
17 17 name: 'BreadcrumbItem',
... ... @@ -42,7 +42,7 @@
42 42 onMounted(() => {
43 43 const link = unref(linkRef);
44 44 if (!link) return;
45   - useEvent({
  45 + useEventListener({
46 46 el: link,
47 47 listener: () => {
48 48 const { to } = props;
... ...
src/components/Container/src/LazyContainer.vue
... ... @@ -22,8 +22,7 @@
22 22 import { defineComponent, reactive, onMounted, ref, toRef, toRefs } from 'vue';
23 23  
24 24 import { Skeleton } from 'ant-design-vue';
25   - import { useTimeout } from '/@/hooks/core/useTimeout';
26   - import { useIntersectionObserver } from '/@/hooks/event/useIntersectionObserver';
  25 + import { useTimeoutFn, useIntersectionObserver } from '@vueuse/core';
27 26 interface State {
28 27 isInit: boolean;
29 28 loading: boolean;
... ... @@ -93,7 +92,7 @@
93 92 function immediateInit() {
94 93 const { timeout } = props;
95 94 timeout &&
96   - useTimeout(() => {
  95 + useTimeoutFn(() => {
97 96 init();
98 97 }, timeout);
99 98 }
... ... @@ -101,7 +100,7 @@
101 100 function init() {
102 101 state.loading = true;
103 102  
104   - useTimeout(() => {
  103 + useTimeoutFn(() => {
105 104 if (state.isInit) return;
106 105 state.isInit = true;
107 106 emit('init');
... ...
src/components/Container/src/collapse/CollapseContainer.vue
... ... @@ -32,7 +32,8 @@
32 32  
33 33 import { triggerWindowResize } from '/@/utils/event/triggerWindowResizeEvent';
34 34 // hook
35   - import { useTimeout } from '/@/hooks/core/useTimeout';
  35 + import { useTimeoutFn } from '@vueuse/core';
  36 +
36 37 export default defineComponent({
37 38 components: {
38 39 Skeleton,
... ... @@ -89,7 +90,7 @@
89 90  
90 91 if (props.triggerWindowResize) {
91 92 // 这里200毫秒是因为展开有动画,
92   - useTimeout(triggerWindowResize, 200);
  93 + useTimeoutFn(triggerWindowResize, 200);
93 94 }
94 95 }
95 96 return {
... ...
src/components/CountTo/src/index.vue
... ... @@ -6,15 +6,13 @@
6 6 <script lang="ts">
7 7 import { defineComponent, reactive, computed, watch, onMounted, unref, toRef } from 'vue';
8 8 import { countToProps } from './props';
9   - import { useRaf } from '/@/hooks/event/useRaf';
10 9 import { isNumber } from '/@/utils/is';
  10 + import { requestAnimationFrame, cancelAnimationFrame } from '/@/utils/animation';
11 11 export default defineComponent({
12 12 name: 'CountTo',
13 13 props: countToProps,
14 14 emits: ['mounted', 'callback'],
15 15 setup(props, { emit }) {
16   - const { requestAnimationFrame, cancelAnimationFrame } = useRaf();
17   -
18 16 const state = reactive<{
19 17 localStartVal: number;
20 18 printVal: number | null;
... ...
src/components/Modal/src/Modal.tsx
1 1 import { Modal } from 'ant-design-vue';
2 2 import { defineComponent, watchEffect } from 'vue';
3 3 import { basicProps } from './props';
4   -import { useTimeout } from '/@/hooks/core/useTimeout';
  4 +import { useTimeoutFn } from '@vueuse/core';
5 5 import { extendSlots } from '/@/utils/helper/tsxHelper';
6 6  
7 7 export default defineComponent({
... ... @@ -99,7 +99,7 @@ export default defineComponent({
99 99 if (!props.visible) {
100 100 return;
101 101 }
102   - useTimeout(() => {
  102 + useTimeoutFn(() => {
103 103 handleDrag();
104 104 }, 30);
105 105 });
... ...
src/components/Modal/src/ModalWrapper.tsx
... ... @@ -14,8 +14,7 @@ import {
14 14 } from 'vue';
15 15 import { Spin } from 'ant-design-vue';
16 16  
17   -import { useWindowSizeFn } from '/@/hooks/event/useWindowSize';
18   -// import { useTimeout } from '/@/hooks/core/useTimeout';
  17 +import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
19 18  
20 19 import { getSlot } from '/@/utils/helper/tsxHelper';
21 20 import { useElResize } from '/@/hooks/event/useElResize';
... ... @@ -126,17 +125,6 @@ export default defineComponent({
126 125 }
127 126 await nextTick();
128 127 const spinEl = unref(spinRef);
129   - // if (!spinEl) {
130   - // useTimeout(() => {
131   - // // retry
132   - // if (tryCount < 3) {
133   - // setModalHeight();
134   - // }
135   - // tryCount++;
136   - // }, 10);
137   - // return;
138   - // }
139   - // tryCount = 0;
140 128  
141 129 const spinContainerEl = spinEl.$el.querySelector('.ant-spin-container') as HTMLElement;
142 130 if (!spinContainerEl) return;
... ...
src/components/Table/src/BasicTable.vue
... ... @@ -64,7 +64,7 @@
64 64 import { useTableScroll } from './hooks/useTableScroll';
65 65 import { provideTable } from './hooks/useProvinceTable';
66 66  
67   - import { useEvent } from '/@/hooks/event/useEvent';
  67 + import { useEventListener } from '/@/hooks/event/useEventListener';
68 68 import { basicProps } from './props';
69 69 import { ROW_KEY } from './const';
70 70 import './style/index.less';
... ... @@ -245,7 +245,7 @@
245 245 }
246 246 const bodyDomList = tableEl.$el.querySelectorAll('.ant-table-body') as HTMLDivElement[];
247 247 const bodyDom = bodyDomList[0];
248   - useEvent({
  248 + useEventListener({
249 249 el: bodyDom,
250 250 name: 'scroll',
251 251 listener: () => {
... ...
src/components/Table/src/hooks/useDataSource.ts
... ... @@ -3,7 +3,7 @@ import type { PaginationProps } from &#39;../types/pagination&#39;;
3 3  
4 4 import { watch, ref, unref, ComputedRef, computed, onMounted, Ref } from 'vue';
5 5  
6   -import { useTimeout } from '/@/hooks/core/useTimeout';
  6 +import { useTimeoutFn } from '@vueuse/core';
7 7  
8 8 import { buildUUID } from '/@/utils/uuid';
9 9 import { isFunction, isBoolean } from '/@/utils/is';
... ... @@ -145,7 +145,7 @@ export function useDataSource(
145 145 }
146 146 onMounted(() => {
147 147 // 转异步任务
148   - useTimeout(() => {
  148 + useTimeoutFn(() => {
149 149 unref(propsRef).immediate && fetch();
150 150 }, 0);
151 151 });
... ...
src/components/Table/src/hooks/useTableScroll.ts
... ... @@ -6,7 +6,7 @@ import { injectModal } from &#39;/@/components/Modal/src/provideModal&#39;;
6 6 import { getViewportOffset } from '/@/utils/domUtils';
7 7 import { isBoolean } from '/@/utils/is';
8 8  
9   -import { useWindowSizeFn } from '/@/hooks/event/useWindowSize';
  9 +import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
10 10 import { useProps } from './useProps';
11 11  
12 12 export function useTableScroll(refProps: ComputedRef<BasicTableProps>, tableElRef: Ref<any>) {
... ... @@ -110,17 +110,6 @@ export function useTableScroll(refProps: ComputedRef&lt;BasicTableProps&gt;, tableElRe
110 110 nextTick(() => {
111 111 calcTableHeight();
112 112 });
113   - // const hasFixedLeft = (unref(propsRef).columns || []).some((item) => item.fixed === 'left');
114   - // // TODO antv table问题情况太多,只能先用下面方式定时器hack
115   - // useTimeout(() => {
116   - // calcTableHeight(() => {
117   - // // 有左侧固定列的时候才有问题
118   - // hasFixedLeft &&
119   - // useTimeout(() => {
120   - // triggerWindowResize();
121   - // }, 300);
122   - // });
123   - // }, 200);
124 113 }
125 114 });
126 115 const getScrollRef = computed(() => {
... ...
src/components/Verify/src/DragVerify.tsx
1 1 import { defineComponent, ref, computed, unref, reactive, watch, watchEffect } from 'vue';
2   -import { useTimeout } from '/@/hooks/core/useTimeout';
3   -import { useEvent } from '/@/hooks/event/useEvent';
  2 +import { useTimeoutFn } from '@vueuse/core';
  3 +import { useEventListener } from '/@/hooks/event/useEventListener';
4 4 import { basicProps } from './props';
5 5 import { getSlot } from '/@/utils/helper/tsxHelper';
6 6 import './DragVerify.less';
... ... @@ -91,7 +91,7 @@ export default defineComponent({
91 91 return (e as MouseEvent).pageX || (e as TouchEvent).touches[0].pageX;
92 92 }
93 93  
94   - useEvent({
  94 + useEventListener({
95 95 el: document,
96 96 name: 'mouseup',
97 97 listener: () => {
... ... @@ -201,7 +201,7 @@ export default defineComponent({
201 201 const contentEl = unref(contentElRef);
202 202 if (!actionEl || !barEl || !contentEl) return;
203 203 state.toLeft = true;
204   - useTimeout(() => {
  204 + useTimeoutFn(() => {
205 205 state.toLeft = false;
206 206 actionEl.style.left = '0';
207 207 barEl.style.width = '0';
... ...
src/components/Verify/src/ImgRotate.tsx
1 1 import type { MoveData, DragVerifyActionType } from './types';
2 2  
3 3 import { defineComponent, computed, unref, reactive, watch, ref, getCurrentInstance } from 'vue';
4   -import { useTimeout } from '/@/hooks/core/useTimeout';
  4 +import { useTimeoutFn } from '@vueuse/core';
5 5  
6 6 import BasicDragVerify from './DragVerify';
7 7  
... ... @@ -86,7 +86,7 @@ export default defineComponent({
86 86 if (Math.abs(randomRotate - currentRotate) >= (diffDegree || 20)) {
87 87 state.imgStyle = hackCss('transform', `rotateZ(${randomRotate}deg)`);
88 88 state.toOrigin = true;
89   - useTimeout(() => {
  89 + useTimeoutFn(() => {
90 90 state.toOrigin = false;
91 91 state.showTip = true;
92 92 // 时间与动画时间保持一致
... ...
src/components/Verify/src/VerifyModal.vue
1 1 <script lang="tsx">
2 2 import { defineComponent, ref, unref } from 'vue';
3 3 import { BasicModal } from '/@/components/Modal/index';
4   - import { useTimeout } from '/@/hooks/core/useTimeout';
  4 + import { useTimeoutFn } from '@vueuse/core';
5 5  
6 6 import { RotateDragVerify, DragVerifyActionType } from '/@/components/Verify/index';
7 7 export default defineComponent({
... ... @@ -11,7 +11,7 @@
11 11 const dragRef = ref<DragVerifyActionType | null>(null);
12 12  
13 13 function handleSuccess() {
14   - useTimeout(() => {
  14 + useTimeoutFn(() => {
15 15 emit('success');
16 16 const dragEl = unref(dragRef);
17 17 if (dragEl) {
... ...
src/components/VirtualScroll/src/index.tsx
1 1 import { defineComponent, computed, ref, unref, reactive, onMounted, watch, nextTick } from 'vue';
2   -import { useEvent } from '/@/hooks/event/useEvent';
  2 +import { useEventListener } from '/@/hooks/event/useEventListener';
3 3  
4 4 import { convertToUnit } from '/@/components/util';
5 5 import { props as basicProps } from './props';
... ... @@ -109,7 +109,7 @@ export default defineComponent({
109 109 if (!wrapEl) {
110 110 return;
111 111 }
112   - useEvent({
  112 + useEventListener({
113 113 el: wrapEl,
114 114 name: 'scroll',
115 115 listener: onScroll,
... ...
src/hooks/core/asyncComputed.ts deleted 100644 → 0
1   -import { ref, watchEffect, Ref } from 'vue';
2   -
3   -/**
4   - * Handle overlapping async evaluations
5   - *
6   - * @param cancelCallback The provided callback is invoked when a re-evaluation of the computed value is triggered before the previous one finished
7   - */
8   -export type AsyncComputedOnCancel = (cancelCallback: () => void) => void;
9   -
10   -/**
11   - * A two-item tuple with the first item being a ref to the computed value and the second item holding a boolean ref, indicating whether the async computed value is currently (re-)evaluated
12   - */
13   -export type AsyncComputedResult<T> = [Ref<T>, Ref<boolean>];
14   -
15   -/**
16   - * Create an asynchronous computed dependency
17   - *
18   - * @param evaluationCallback The promise-returning callback which generates the computed value
19   - * @param defaultValue A default value, used until the first evaluation finishes
20   - */
21   -export function asyncComputed<T>(
22   - evaluationCallback: (onCancel: AsyncComputedOnCancel) => T | Promise<T>,
23   - defaultValue?: T
24   -): AsyncComputedResult<T> {
25   - let counter = 0;
26   - const current = ref(defaultValue) as Ref<T>;
27   - const evaluating = ref<boolean>(false);
28   -
29   - watchEffect(async (onInvalidate: Fn) => {
30   - counter++;
31   - const counterAtBeginning = counter;
32   - let hasFinished = false;
33   -
34   - try {
35   - // Defer initial setting of `evaluating` ref
36   - // to avoid having it as a dependency
37   - Promise.resolve().then(() => {
38   - evaluating.value = true;
39   - });
40   -
41   - const result = await evaluationCallback((cancelCallback) => {
42   - onInvalidate(() => {
43   - evaluating.value = false;
44   - if (!hasFinished) cancelCallback();
45   - });
46   - });
47   -
48   - if (counterAtBeginning === counter) current.value = result;
49   - } finally {
50   - evaluating.value = false;
51   - hasFinished = true;
52   - }
53   - });
54   -
55   - return [current, evaluating];
56   -}
src/hooks/core/useCounter.ts deleted 100644 → 0
1   -import { ref } from 'vue';
2   -
3   -export function useCounter(initialValue = 0) {
4   - const count = ref(initialValue);
5   -
6   - const inc = (delta = 1) => (count.value += delta);
7   - const dec = (delta = 1) => (count.value -= delta);
8   - const get = () => count.value;
9   - const set = (val: number) => (count.value = val);
10   - const reset = (val = initialValue) => {
11   - initialValue = val;
12   - return set(val);
13   - };
14   -
15   - return { count, inc, dec, get, set, reset };
16   -}
src/hooks/core/useTimeout.ts deleted 100644 → 0
1   -import { isFunction } from '/@/utils/is';
2   -import { Ref, watch } from 'vue';
3   -
4   -import { useTimeoutRef } from '/@/hooks/core/useTimeoutRef';
5   -
6   -type TimeoutFnResult = [Fn<void>, Fn<void>, Ref<boolean>];
7   -
8   -export function useTimeout(handle: Fn<any>, wait: number): TimeoutFnResult {
9   - if (!isFunction(handle)) {
10   - throw new Error('handle is not Function!');
11   - }
12   -
13   - const [readyRef, clear, runAgain] = useTimeoutRef(wait);
14   -
15   - watch(
16   - readyRef,
17   - (maturity) => {
18   - maturity && handle();
19   - },
20   - { immediate: false }
21   - );
22   - return [clear, runAgain, readyRef];
23   -}
src/hooks/core/useTimeoutRef.ts deleted 100644 → 0
1   -import { Ref, ref } from 'vue';
2   -import { tryOnUnmounted } from '/@/utils/helper/vueHelper';
3   -export type TimeoutResult = [Ref<boolean>, Fn<void>, Fn<void>];
4   -export function useTimeoutRef(wait: number): TimeoutResult {
5   - const readyRef = ref(false);
6   -
7   - let timer: ReturnType<typeof setTimeout> | undefined;
8   - function clear(): void {
9   - readyRef.value = false;
10   - timer && window.clearTimeout(timer);
11   - }
12   - function openTimer(): void {
13   - clear();
14   - timer = setTimeout(() => {
15   - readyRef.value = true;
16   - }, wait);
17   - }
18   -
19   - openTimer();
20   -
21   - tryOnUnmounted(clear);
22   -
23   - return [readyRef, clear, openTimer];
24   -}
src/hooks/event/useBreakpoint.ts
1   -import { ref, computed, Ref, unref } from 'vue';
2   -import { useEvent } from './useEvent';
  1 +import { ref, computed, ComputedRef, unref } from 'vue';
  2 +import { useEventListener } from '/@/hooks/event/useEventListener';
3 3 import { screenMap, sizeEnum, screenEnum } from '/@/enums/breakpointEnum';
4 4  
5   -let globalScreenRef: Ref<sizeEnum | undefined>;
6   -let globalWidthRef: Ref<number>;
7   -let globalRealWidthRef: Ref<number>;
  5 +let globalScreenRef: ComputedRef<sizeEnum | undefined>;
  6 +let globalWidthRef: ComputedRef<number>;
  7 +let globalRealWidthRef: ComputedRef<number>;
8 8  
9 9 export function useBreakpoint() {
10 10 return {
... ... @@ -43,7 +43,7 @@ export function createBreakpointListen(fn?: Fn) {
43 43 realWidthRef.value = width;
44 44 }
45 45  
46   - useEvent({
  46 + useEventListener({
47 47 el: window,
48 48 name: 'resize',
49 49 listener: () => {
... ...
src/hooks/event/useEventHub.ts deleted 100644 → 0
1   -import { tryOnUnmounted } from '/@/utils/helper/vueHelper';
2   -import EventHub from '/@/utils/eventHub';
3   -const eventHub = new EventHub();
4   -export function useEventHub(): EventHub {
5   - tryOnUnmounted(() => {
6   - eventHub.clear();
7   - });
8   -
9   - return eventHub;
10   -}
src/hooks/event/useEvent.ts renamed to src/hooks/event/useEventListener.ts
... ... @@ -15,7 +15,7 @@ export interface UseEventParams {
15 15 isDebounce?: boolean;
16 16 wait?: number;
17 17 }
18   -export function useEvent({
  18 +export function useEventListener({
19 19 el = window,
20 20 name,
21 21 listener,
... ...
src/hooks/event/useIntersectionObserver.ts deleted 100644 → 0
1   -import { Ref, watchEffect, ref } from 'vue';
2   -
3   -interface IntersectionObserverProps {
4   - target: Ref<Element | null | undefined>;
5   - root?: Ref<Element | null | undefined>;
6   - onIntersect: IntersectionObserverCallback;
7   - rootMargin?: string;
8   - threshold?: number;
9   -}
10   -
11   -export function useIntersectionObserver({
12   - target,
13   - root,
14   - onIntersect,
15   - rootMargin = '0px',
16   - threshold = 0.1,
17   -}: IntersectionObserverProps) {
18   - let cleanup = () => {};
19   - const observer: Ref<Nullable<IntersectionObserver>> = ref(null);
20   - const stopEffect = watchEffect(() => {
21   - cleanup();
22   -
23   - observer.value = new IntersectionObserver(onIntersect, {
24   - root: root ? root.value : null,
25   - rootMargin,
26   - threshold,
27   - });
28   -
29   - const current = target.value;
30   -
31   - current && observer.value.observe(current);
32   -
33   - cleanup = () => {
34   - if (observer.value) {
35   - observer.value.disconnect();
36   - target.value && observer.value.unobserve(target.value);
37   - }
38   - };
39   - });
40   -
41   - return {
42   - observer,
43   - stop: () => {
44   - cleanup();
45   - stopEffect();
46   - },
47   - };
48   -}
src/hooks/event/useNow.ts deleted 100644 → 0
1   -import { ref } from 'vue';
2   -import { tryOnUnmounted } from '/@/utils/helper/vueHelper';
3   -
4   -function getTimestamp() {
5   - return +Date.now();
6   -}
7   -
8   -export function useNow() {
9   - const now = ref(getTimestamp());
10   - let started = false;
11   -
12   - const update = () => {
13   - requestAnimationFrame(() => {
14   - now.value = getTimestamp();
15   - if (started) update();
16   - });
17   - };
18   -
19   - const start = () => {
20   - if (!started) {
21   - started = true;
22   - update();
23   - }
24   - };
25   -
26   - const stop = () => {
27   - started = false;
28   - };
29   -
30   - start();
31   -
32   - tryOnUnmounted(stop);
33   -
34   - return now;
35   -}
src/hooks/event/useScrollTo.ts
1   -import { useRaf } from '/@/hooks/event/useRaf';
2 1 import { isFunction, isUnDef } from '/@/utils/is';
3 2 import { ref, unref } from 'vue';
  3 +import { requestAnimationFrame } from '/@/utils/animation';
  4 +
4 5 export interface ScrollToParams {
5 6 el: HTMLElement;
6 7 to: number;
... ... @@ -30,7 +31,6 @@ export function useScrollTo({ el, to, duration = 500, callback }: ScrollToParams
30 31 const increment = 20;
31 32 let currentTime = 0;
32 33 duration = isUnDef(duration) ? 500 : duration;
33   - const { requestAnimationFrame } = useRaf();
34 34  
35 35 const animateScroll = function () {
36 36 if (!unref(isActiveRef)) {
... ...
src/hooks/event/useWindowSize.ts renamed to src/hooks/event/useWindowSizeFn.ts
1 1 import { tryOnMounted, tryOnUnmounted } from '/@/utils/helper/vueHelper';
2   -import { ref } from 'vue';
3 2  
4 3 import { useDebounce } from '/@/hooks/core/useDebounce';
5 4  
... ... @@ -37,22 +36,3 @@ export function useWindowSizeFn&lt;T&gt;(fn: Fn&lt;T&gt;, wait = 150, options?: WindowSizeOp
37 36 });
38 37 return [start, stop];
39 38 }
40   -
41   -export const useWindowSize = (wait = 150, options?: WindowSizeOptions) => {
42   - const widthRef = ref(0);
43   - const heightRef = ref(0);
44   -
45   - function setSize() {
46   - widthRef.value = window.innerWidth;
47   - heightRef.value = window.innerHeight;
48   - }
49   - setSize();
50   -
51   - const handler = () => {
52   - setSize();
53   - };
54   -
55   - useWindowSizeFn(handler, wait, options);
56   -
57   - return { widthRef: widthRef, heightRef: heightRef };
58   -};
... ...
src/hooks/state/useGlobalState.ts deleted 100644 → 0
1   -import { reactive } from 'vue';
2   -
3   -export function createGlobalState<T extends object>(factory: () => T) {
4   - let state: T;
5   -
6   - return () => {
7   - if (!state) {
8   - state = reactive(factory()) as T;
9   - }
10   - return state;
11   - };
12   -}
src/hooks/web/useApexCharts.ts
1   -import { useTimeout } from '/@/hooks/core/useTimeout';
  1 +import { useTimeoutFn } from '@vueuse/core';
2 2 import { tryOnUnmounted } from '/@/utils/helper/vueHelper';
3 3 import { unref, Ref, nextTick } from 'vue';
4 4  
... ... @@ -9,7 +9,7 @@ export function useApexCharts(elRef: Ref&lt;HTMLDivElement&gt;) {
9 9  
10 10 function setOptions(options: any) {
11 11 nextTick(() => {
12   - useTimeout(() => {
  12 + useTimeoutFn(() => {
13 13 const el = unref(elRef);
14 14  
15 15 if (!el || !unref(el)) return;
... ...
src/hooks/web/useClickOutside.ts
1 1 import { ref, Ref, unref } from 'vue';
2   -import { useEvent } from '/@/hooks/event/useEvent';
  2 +import { useEventListener } from '/@/hooks/event/useEventListener';
3 3 export function useClickOutside<T extends HTMLElement>(
4 4 containerRef: Ref<T>,
5 5 onClickOutside: (e: MouseEvent | TouchEvent) => void
6 6 ) {
7 7 const isTouchRef = ref(false);
8   - useEvent({
  8 + useEventListener({
9 9 el: document,
10 10 name: 'touchend',
11 11 listener: handler,
12 12 options: true,
13 13 });
14   - useEvent({
  14 + useEventListener({
15 15 el: document,
16 16 name: 'click',
17 17 listener: handler,
... ...
src/hooks/web/useCssVar.ts deleted 100644 → 0
1   -// import { ref, Ref, isRef, watch } from '@vue/runtime-dom';
2   -
3   -// TODO 打开注释会造成热更新失效,待排查
4   -// export default function useCssVar(prop: string, refEl?: Ref<HTMLElement | null>) {
5   -// const refVar = ref('');
6   -// let el: HTMLElement = document.documentElement;
7   -
8   -// if (isRef(refEl)) {
9   -// watch(
10   -// refEl,
11   -// () => {
12   -// if (refEl.value) {
13   -// el = refEl.value as HTMLElement;
14   -// refVar.value = getComputedStyle(el).getPropertyValue(prop);
15   -// }
16   -// },
17   -// { immediate: true }
18   -// );
19   -// } else {
20   -// refVar.value = getComputedStyle(el).getPropertyValue(prop);
21   -// }
22   -
23   -// watch(
24   -// refVar,
25   -// (val) => {
26   -// el && el.style.setProperty(prop, val);
27   -// },
28   -// { immediate: true }
29   -// );
30   -
31   -// return refVar;
32   -// }
33   -
34   -export function getCssVar(prop: string, dom = document.documentElement) {
35   - return getComputedStyle(dom).getPropertyValue(prop);
36   -}
37   -
38   -export function setCssVar(prop: string, val: any, dom = document.documentElement) {
39   - dom.style.setProperty(prop, val);
40   -}
src/hooks/web/useECharts.ts
1   -import { useTimeout } from '/@/hooks/core/useTimeout';
  1 +import { useTimeoutFn } from '@vueuse/core';
2 2 import { tryOnUnmounted } from '/@/utils/helper/vueHelper';
3 3 import { unref, Ref, nextTick } from 'vue';
4 4 import type { EChartOption, ECharts } from 'echarts';
5 5 import echarts from 'echarts';
6 6 import { useDebounce } from '/@/hooks/core/useDebounce';
7   -import { useEvent } from '/@/hooks/event/useEvent';
  7 +import { useEventListener } from '/@/hooks/event/useEventListener';
8 8 import { useBreakpoint } from '/@/hooks/event/useBreakpoint';
9 9  
10 10 export type { EChartOption, ECharts };
... ... @@ -26,7 +26,7 @@ export function useECharts(
26 26 return;
27 27 }
28 28 chartInstance = echarts.init(el, theme);
29   - const { removeEvent } = useEvent({
  29 + const { removeEvent } = useEventListener({
30 30 el: window,
31 31 name: 'resize',
32 32 listener: resizeFn,
... ... @@ -34,7 +34,7 @@ export function useECharts(
34 34 removeResizeFn = removeEvent;
35 35 const { widthRef, screenEnum } = useBreakpoint();
36 36 if (unref(widthRef) <= screenEnum.MD) {
37   - useTimeout(() => {
  37 + useTimeoutFn(() => {
38 38 resizeFn();
39 39 }, 30);
40 40 }
... ... @@ -42,7 +42,7 @@ export function useECharts(
42 42  
43 43 function setOptions(options: any, clear = true) {
44 44 nextTick(() => {
45   - useTimeout(() => {
  45 + useTimeoutFn(() => {
46 46 if (!chartInstance) {
47 47 init();
48 48  
... ...
src/hooks/web/useLocalStorage.ts deleted 100644 → 0
1   -import { createStorage } from '/@/utils/storage';
2   -
3   -export function useLocalStorage() {
4   - return createStorage(localStorage);
5   -}
src/hooks/web/useNetWork.ts deleted 100644 → 0
1   -import type { Ref } from 'vue';
2   -
3   -import { ref, watch } from 'vue';
4   -import { tryOnMounted, tryOnUnmounted } from '/@/utils/helper/vueHelper';
5   -
6   -import { isBoolean } from '/@/utils/is';
7   -
8   -const ON_LINE = 'online';
9   -const OFF_LINE = 'offline';
10   -export function useNetWork({
11   - onLineFn,
12   - offLineFn,
13   -}: {
14   - onLineFn?: () => void;
15   - offLineFn?: () => void;
16   -}) {
17   - const onLineRef = ref(navigator.onLine);
18   -
19   - // Disconnect time
20   - const offlineAt: Ref<number | undefined> = ref(undefined);
21   -
22   - watch(
23   - () => onLineRef.value,
24   - (onLine, oldValue): void => {
25   - if (isBoolean(oldValue) && !oldValue && onLine) {
26   - onLineFn && onLineFn();
27   - } else if (isBoolean(onLine) && !onLine && oldValue) {
28   - // Network to no network
29   - offlineAt.value = Date.now();
30   - offLineFn && offLineFn();
31   - }
32   - },
33   - {
34   - immediate: false,
35   - }
36   - );
37   -
38   - const handler = (e: Event) => {
39   - const { type } = e;
40   - onLineRef.value = type === ON_LINE;
41   - };
42   - tryOnMounted(() => {
43   - window.addEventListener(ON_LINE, handler);
44   - window.addEventListener(OFF_LINE, handler);
45   - });
46   - tryOnUnmounted(() => {
47   - window.removeEventListener(ON_LINE, handler);
48   - window.removeEventListener(OFF_LINE, handler);
49   - });
50   - return {
51   - onLineRef,
52   - };
53   -}
src/hooks/web/useSessionStorage.ts deleted 100644 → 0
1   -import { createStorage } from '/@/utils/storage';
2   -
3   -export function useSessionStorage() {
4   - return createStorage(sessionStorage);
5   -}
src/hooks/web/useTabs.ts
1   -import { useTimeout } from '/@/hooks/core/useTimeout';
  1 +import { useTimeoutFn } from '@vueuse/core';
2 2 import { PageEnum } from '/@/enums/pageEnum';
3 3 import { TabItem, tabStore } from '/@/store/modules/tab';
4 4 import { appStore } from '/@/store/modules/app';
... ... @@ -98,7 +98,7 @@ export function useTabs() {
98 98 const to = getTo(path);
99 99  
100 100 if (!to) return;
101   - useTimeout(() => {
  101 + useTimeoutFn(() => {
102 102 tabStore.addTabByPathAction();
103 103 }, 0);
104 104 const { replace, query = {}, params = {} } = opt || {};
... ...
src/hooks/web/useTitle.ts deleted 100644 → 0
1   -import type { Ref } from 'vue';
2   -
3   -import { ref, watch } from 'vue';
4   -import { tryOnUnmounted } from '/@/utils/helper/vueHelper';
5   -import { isString } from '/@/utils/is';
6   -
7   -export function useTitle(overrideTitle: string | null = null): Ref<string | null> {
8   - const title = ref<string | null>(isString(overrideTitle) ? overrideTitle : document.title);
9   - const observer = new MutationObserver((m) => {
10   - title.value = m[0].target.textContent;
11   - });
12   -
13   - watch(
14   - title,
15   - (t, o) => {
16   - if (isString(t) && t !== o) {
17   - document.title = t;
18   - }
19   - },
20   - {
21   - immediate: true,
22   - flush: 'sync',
23   - }
24   - );
25   -
26   - const titleElement = document.querySelector('title')!;
27   - observer.observe(titleElement, { childList: true });
28   - tryOnUnmounted(() => {
29   - observer.disconnect();
30   - });
31   - return title;
32   -}
src/hooks/web/useVisibilityState.ts deleted 100644 → 0
1   -import { ref, onUnmounted, computed } from '@vue/runtime-dom';
2   -import { isDef } from '/@/utils/is';
3   -
4   -export default function useVisibilityState() {
5   - const refVisibility = ref(true);
6   -
7   - if (isDef(document) && isDef(document.visibilityState)) {
8   - const setVisibility = () => {
9   - refVisibility.value = document.visibilityState === 'visible';
10   - };
11   -
12   - document.addEventListener('visibilitychange', setVisibility, false);
13   -
14   - onUnmounted(() => {
15   - document.removeEventListener('visibilitychange', setVisibility);
16   - });
17   - }
18   -
19   - return computed(() => refVisibility.value);
20   -}
src/layouts/default/header/LayoutHeader.tsx
... ... @@ -19,7 +19,7 @@ import {
19 19  
20 20 import { useFullscreen } from '/@/hooks/web/useFullScreen';
21 21 import { useTabs } from '/@/hooks/web/useTabs';
22   -import { useWindowSizeFn } from '/@/hooks/event/useWindowSize';
  22 +import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
23 23 import { useRouter } from 'vue-router';
24 24 import { useModal } from '/@/components/Modal';
25 25  
... ...
src/layouts/logo/index.vue
... ... @@ -8,7 +8,7 @@
8 8 import { computed, defineComponent, PropType, ref, watch } from 'vue';
9 9 // hooks
10 10 import { useSetting } from '/@/hooks/core/useSetting';
11   - import { useTimeout } from '/@/hooks/core/useTimeout';
  11 + import { useTimeoutFn } from '@vueuse/core';
12 12 import { useGo } from '/@/hooks/web/usePage';
13 13  
14 14 import { PageEnum } from '/@/enums/pageEnum';
... ... @@ -41,7 +41,7 @@
41 41 () => props.showTitle,
42 42 (show: boolean) => {
43 43 if (show) {
44   - useTimeout(() => {
  44 + useTimeoutFn(() => {
45 45 showRef.value = show;
46 46 }, 280);
47 47 } else {
... ...
src/settings/projectSetting.ts
... ... @@ -128,9 +128,6 @@ const setting: ProjectConfig = {
128 128 // 是否开启登录安全校验
129 129 openLoginVerify: true,
130 130  
131   - // 是否监听网络变化
132   - listenNetWork: false,
133   -
134 131 // 是否开启页面切换loading
135 132 openPageLoading: true,
136 133  
... ...
src/setup/theme/index.ts
1   -import { setCssVar } from '/@/hooks/web/useCssVar';
2 1 import { isHexColor, colorIsDark, lighten, darken } from '/@/utils/color';
3 2 import { appStore } from '/@/store/modules/app';
4 3 import { MenuThemeEnum } from '/@/enums/menuEnum';
... ... @@ -12,6 +11,10 @@ const SIDER_DARK_DARKEN_BG_COLOR = &#39;--sider-dark-darken-bg-color&#39;;
12 11 const SIDER_LIGHTEN_1_BG_COLOR = '--sider-dark-lighten-1-bg-color';
13 12 const SIDER_LIGHTEN_2_BG_COLOR = '--sider-dark-lighten-2-bg-color';
14 13  
  14 +export function setCssVar(prop: string, val: any, dom = document.documentElement) {
  15 + dom.style.setProperty(prop, val);
  16 +}
  17 +
15 18 function toggleClass(flag: boolean, clsName: string) {
16 19 const body = document.body;
17 20 let { className } = body;
... ...
src/types/config.d.ts
... ... @@ -101,8 +101,6 @@ export interface ProjectConfig {
101 101 routerTransition: RouterTransitionEnum;
102 102 // 是否开启登录安全校验
103 103 openLoginVerify: boolean;
104   - // 是否监听网络变化
105   - listenNetWork: boolean;
106 104 // 是否开启页面切换loading
107 105 openPageLoading: boolean;
108 106 // 是否开启回到顶部
... ...
src/useApp.ts
... ... @@ -17,11 +17,6 @@ import {
17 17 } from '/@/setup/theme';
18 18  
19 19 import { appStore } from '/@/store/modules/app';
20   -import { useNetWork } from '/@/hooks/web/useNetWork';
21   -import { useRouter } from 'vue-router';
22   -import { PageEnum } from '/@/enums/pageEnum';
23   -import { useTimeout } from '/@/hooks/core/useTimeout';
24   -import { ExceptionEnum } from '/@/enums/exceptionEnum';
25 20  
26 21 let app: App;
27 22 export function setApp(_app: App): void {
... ... @@ -84,28 +79,3 @@ export function useConfigProvider() {
84 79 transformCellText,
85 80 };
86 81 }
87   -
88   -// Initialize network monitoring
89   -export function useListenerNetWork() {
90   - const { listenNetWork } = appStore.getProjectConfig;
91   - if (!listenNetWork) return;
92   - const { replace } = useRouter();
93   - // Check network status
94   - useNetWork({
95   - onLineFn: () => {
96   - replace(PageEnum.BASE_HOME).then(() => {
97   - useTimeout(() => {
98   - appStore.commitPageLoadingState(false);
99   - }, 200);
100   - });
101   - },
102   - offLineFn: () => {
103   - replace({
104   - path: PageEnum.ERROR_PAGE,
105   - query: {
106   - status: String(ExceptionEnum.NET_WORK_ERROR),
107   - },
108   - });
109   - },
110   - });
111   -}
... ...
src/hooks/event/useRaf.ts renamed to src/utils/animation.ts
1 1 import { isServer } from '/@/utils/is';
2   -import { onUnmounted, getCurrentInstance } from 'vue';
3 2 let lastTime = 0;
4   -const prefixes = 'webkit moz ms o'.split(' '); // Each browser prefix
5   -
6   -let requestAnimationFrame: any;
7   -let cancelAnimationFrame: any;
8   -
9   -/* eslint-disable-next-line */
10   -const NO_LOOP = () => {};
11   -
12   -const getWindowFrame = (name: string) => {
13   - return name as any;
14   -};
15   -if (isServer) {
16   - requestAnimationFrame = cancelAnimationFrame = NO_LOOP;
17   -} else {
18   - requestAnimationFrame = window.requestAnimationFrame;
19   - cancelAnimationFrame = window.cancelAnimationFrame;
20   - let prefix;
21   - for (let i = 0; i < prefixes.length; i++) {
22   - if (requestAnimationFrame && cancelAnimationFrame) {
23   - break;
  3 +const prefixes = 'webkit moz ms o'.split(' ');
  4 +
  5 +let requestAnimationFrame: typeof window.requestAnimationFrame;
  6 +let cancelAnimationFrame: typeof window.cancelAnimationFrame;
  7 +(() => {
  8 + const NO_LOOP: any = () => {};
  9 + const getWindowFrame = (name: string) => {
  10 + return name as any;
  11 + };
  12 + if (isServer) {
  13 + requestAnimationFrame = cancelAnimationFrame = NO_LOOP;
  14 + } else {
  15 + requestAnimationFrame = window.requestAnimationFrame;
  16 + cancelAnimationFrame = window.cancelAnimationFrame;
  17 + let prefix;
  18 + for (let i = 0; i < prefixes.length; i++) {
  19 + if (requestAnimationFrame && cancelAnimationFrame) {
  20 + break;
  21 + }
  22 + prefix = prefixes[i];
  23 + requestAnimationFrame =
  24 + requestAnimationFrame || window[getWindowFrame(prefix + 'RequestAnimationFrame')];
  25 + cancelAnimationFrame =
  26 + cancelAnimationFrame ||
  27 + window[getWindowFrame(prefix + 'CancelAnimationFrame')] ||
  28 + window[getWindowFrame(prefix + 'CancelRequestAnimationFrame')];
24 29 }
25   - prefix = prefixes[i];
26   - requestAnimationFrame =
27   - requestAnimationFrame || window[getWindowFrame(prefix + 'RequestAnimationFrame')];
28   - cancelAnimationFrame =
29   - cancelAnimationFrame ||
30   - window[getWindowFrame(prefix + 'CancelAnimationFrame')] ||
31   - window[getWindowFrame(prefix + 'CancelRequestAnimationFrame')];
32   - }
33   -
34   - // If the current browser does not support requestAnimationFrame and cancelAnimationFrame, it will fall back to setTimeout
35   - if (!requestAnimationFrame || !cancelAnimationFrame) {
36   - requestAnimationFrame = function (callback: Fn) {
37   - const currTime = new Date().getTime();
38   - const timeToCall = Math.max(0, 16 - (currTime - lastTime));
39   - const id = window.setTimeout(() => {
40   - /* eslint-disable-next-line */
41   - callback(currTime + timeToCall);
42   - }, timeToCall);
43   - lastTime = currTime + timeToCall;
44   - return id;
45   - };
46   -
47   - cancelAnimationFrame = function (id: number) {
48   - window.clearTimeout(id);
49   - };
50   - }
51   -}
52   -export function useRaf() {
53   - // if (getCurrentInstance()) {
54   - // onUnmounted(() => {
55   - // cancelAnimationFrame();
56   - // });
57   - // }
58   - return { requestAnimationFrame, cancelAnimationFrame };
59   -}
60   -
61   -export function useRafFn(fn: (...arg: any) => any, options: { immediate?: boolean } = {}) {
62   - const { immediate = false } = options;
63   - let started = false;
64   - let id: ReturnType<typeof window.requestAnimationFrame>;
65 30  
66   - function loop() {
67   - if (!started) return;
68   - fn();
69   - id = requestAnimationFrame(loop);
70   - }
71   -
72   - function start() {
73   - if (!started) {
74   - started = true;
75   - loop();
  31 + // If the current browser does not support requestAnimationFrame and cancelAnimationFrame, it will fall back to setTimeout
  32 + if (!requestAnimationFrame || !cancelAnimationFrame) {
  33 + requestAnimationFrame = function (callback: Fn) {
  34 + const currTime = new Date().getTime();
  35 + const timeToCall = Math.max(0, 16 - (currTime - lastTime));
  36 + const id = window.setTimeout(() => {
  37 + /* eslint-disable-next-line */
  38 + callback(currTime + timeToCall);
  39 + }, timeToCall);
  40 + lastTime = currTime + timeToCall;
  41 + return id;
  42 + };
  43 +
  44 + cancelAnimationFrame = function (id: number) {
  45 + window.clearTimeout(id);
  46 + };
76 47 }
77 48 }
  49 +})();
78 50  
79   - function stop() {
80   - started = false;
81   - }
82   -
83   - if (immediate) {
84   - start();
85   - }
86   -
87   - if (getCurrentInstance()) {
88   - onUnmounted(() => {
89   - cancelAnimationFrame(id);
90   - stop();
91   - });
92   - }
93   -
94   - return { stop, start };
95   -}
  51 +export { requestAnimationFrame, cancelAnimationFrame };
... ...
src/views/sys/iframe/index.vue
... ... @@ -10,7 +10,7 @@
10 10 import { Spin } from 'ant-design-vue';
11 11  
12 12 import { getViewportOffset } from '/@/utils/domUtils';
13   - import { useWindowSizeFn } from '/@/hooks/event/useWindowSize';
  13 + import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
14 14  
15 15 export default defineComponent({
16 16 name: 'IFrame',
... ...
yarn.lock
... ... @@ -1725,6 +1725,21 @@
1725 1725 vscode-languageserver-textdocument "^1.0.1"
1726 1726 vscode-uri "^2.1.2"
1727 1727  
  1728 +"@vueuse/core@^4.0.0-beta.40":
  1729 + version "4.0.0-beta.40"
  1730 + resolved "https://registry.npmjs.org/@vueuse/core/-/core-4.0.0-beta.40.tgz#7efdc15c1b994647dff7ae65c0ca573d96ce9b28"
  1731 + integrity sha512-FOTOUrXAAp0NOmy8hMlP1HpUhnB8LeRJZDOEUl/A9gKMDwWvPTEvxKsDAIzSa4s7I0MapVzfeP3soNCNfl9+vQ==
  1732 + dependencies:
  1733 + "@vueuse/shared" "4.0.0-beta.40"
  1734 + vue-demi latest
  1735 +
  1736 +"@vueuse/shared@4.0.0-beta.40":
  1737 + version "4.0.0-beta.40"
  1738 + resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-4.0.0-beta.40.tgz#76e9b52228159e7ec88df2c8f4eea8fce1a42ec3"
  1739 + integrity sha512-Ay71viUTXs0XX2hQ04kEExhpsCrw3KankBMP7euorsPjuQmIZjUA4NNOb45UAudg+uF5HXLpgWLvwb4cMOLHnQ==
  1740 + dependencies:
  1741 + vue-demi latest
  1742 +
1728 1743 JSONStream@^1.0.4:
1729 1744 version "1.3.5"
1730 1745 resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
... ... @@ -8233,6 +8248,11 @@ vscode-uri@^2.1.2:
8233 8248 resolved "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz#c8d40de93eb57af31f3c715dd650e2ca2c096f1c"
8234 8249 integrity sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==
8235 8250  
  8251 +vue-demi@latest:
  8252 + version "0.4.3"
  8253 + resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.4.3.tgz#6aaa9b52f02c32b4f9d4d11f02a1ae71031453c3"
  8254 + integrity sha512-1DzLcZgHC9ZyFEYR4qZ83TdS1u9DglG8XVesBXqtbbmqFuO7sb8KG36kMfZCszieAweRDwAAVSAzjmEMG0+WwA==
  8255 +
8236 8256 vue-eslint-parser@^7.1.1:
8237 8257 version "7.1.1"
8238 8258 resolved "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.1.1.tgz#c43c1c715ff50778b9a7e9a4e16921185f3425d3"
... ...