mirror of
https://github.com/vbenjs/gf-vben-admin.git
synced 2025-02-02 19:08:40 +08:00
refactor: refactor hooks
This commit is contained in:
parent
215d8bab38
commit
2037293aa3
@ -1,5 +1,22 @@
|
|||||||
## Wip
|
## Wip
|
||||||
|
|
||||||
|
## (破坏性更新) Breaking changes
|
||||||
|
|
||||||
|
- 使用 `pinia` 替换 `vuex`,`vuex-module-decorators`。
|
||||||
|
|
||||||
|
- 影响,之前如果有自己使用 vuex-module-decorators,需要改造为 pinia。
|
||||||
|
- 原因:
|
||||||
|
- pinia 于 vuex5api 基本类似,且简单易懂。
|
||||||
|
- 后续切换 vuex5 成本非常低,也可以当作第三方状态管理库使用
|
||||||
|
|
||||||
|
- 移除 `useKeyPress` 使用`vueuse`-`onKeyStroke`代替
|
||||||
|
- 移除 `useDebounceFn` 使用`vueuse`-`useDebounceFn`代替
|
||||||
|
- 移除 `useThrottle` 使用`vueuse`-`useThrottleFn`代替
|
||||||
|
|
||||||
|
### ✨ Refactor
|
||||||
|
|
||||||
|
- 移除 `useElResize`
|
||||||
|
|
||||||
### 🐛 Bug Fixes
|
### 🐛 Bug Fixes
|
||||||
|
|
||||||
- 登录页样式修复
|
- 登录页样式修复
|
||||||
|
@ -3,15 +3,13 @@ import type { Menu } from '/@/router/types';
|
|||||||
import { ref, onBeforeMount, unref, Ref, nextTick } from 'vue';
|
import { ref, onBeforeMount, unref, Ref, nextTick } from 'vue';
|
||||||
|
|
||||||
import { getMenus } from '/@/router/menus';
|
import { getMenus } from '/@/router/menus';
|
||||||
import { KeyCodeEnum } from '/@/enums/keyCodeEnum';
|
|
||||||
|
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
import { filter, forEach } from '/@/utils/helper/treeHelper';
|
import { filter, forEach } from '/@/utils/helper/treeHelper';
|
||||||
|
|
||||||
import { useDebounce } from '/@/hooks/core/useDebounce';
|
|
||||||
import { useGo } from '/@/hooks/web/usePage';
|
import { useGo } from '/@/hooks/web/usePage';
|
||||||
import { useScrollTo } from '/@/hooks/event/useScrollTo';
|
import { useScrollTo } from '/@/hooks/event/useScrollTo';
|
||||||
import { useKeyPress } from '/@/hooks/event/useKeyPress';
|
import { onKeyStroke, useDebounceFn } from '@vueuse/core';
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
|
|
||||||
export interface SearchResult {
|
export interface SearchResult {
|
||||||
@ -41,7 +39,7 @@ export function useMenuSearch(refs: Ref<HTMLElement[]>, scrollWrap: Ref<ElRef>,
|
|||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const go = useGo();
|
const go = useGo();
|
||||||
const [handleSearch] = useDebounce(search, 200);
|
const handleSearch = useDebounceFn(search, 200);
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
const list = await getMenus();
|
const list = await getMenus();
|
||||||
@ -146,23 +144,10 @@ export function useMenuSearch(refs: Ref<HTMLElement[]>, scrollWrap: Ref<ElRef>,
|
|||||||
emit('close');
|
emit('close');
|
||||||
}
|
}
|
||||||
|
|
||||||
useKeyPress(['enter', 'up', 'down', 'esc'], (events) => {
|
onKeyStroke('Enter', handleEnter);
|
||||||
const keyCode = events.keyCode;
|
onKeyStroke('ArrowUp', handleUp);
|
||||||
switch (keyCode) {
|
onKeyStroke('ArrowDown', handleDown);
|
||||||
case KeyCodeEnum.UP:
|
onKeyStroke('Escape', handleClose);
|
||||||
handleUp();
|
|
||||||
break;
|
|
||||||
case KeyCodeEnum.DOWN:
|
|
||||||
handleDown();
|
|
||||||
break;
|
|
||||||
case KeyCodeEnum.ENTER:
|
|
||||||
handleEnter();
|
|
||||||
break;
|
|
||||||
case KeyCodeEnum.ESC:
|
|
||||||
handleClose();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return { handleSearch, searchResult, keyword, activeIndex, handleMouseenter, handleEnter };
|
return { handleSearch, searchResult, keyword, activeIndex, handleMouseenter, handleEnter };
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@
|
|||||||
import iconsData from '../data/icons.data';
|
import iconsData from '../data/icons.data';
|
||||||
import { propTypes } from '/@/utils/propTypes';
|
import { propTypes } from '/@/utils/propTypes';
|
||||||
import { usePagination } from '/@/hooks/web/usePagination';
|
import { usePagination } from '/@/hooks/web/usePagination';
|
||||||
import { useDebounce } from '/@/hooks/core/useDebounce';
|
import { useDebounceFn } from '@vueuse/core';
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
|
import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
@ -123,7 +123,7 @@
|
|||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { prefixCls } = useDesign('icon-picker');
|
const { prefixCls } = useDesign('icon-picker');
|
||||||
|
|
||||||
const [debounceHandleSearchChange] = useDebounce(handleSearchChange, 100);
|
const debounceHandleSearchChange = useDebounceFn(handleSearchChange, 100);
|
||||||
const { clipboardRef, isSuccessRef } = useCopyToClipboard(props.value);
|
const { clipboardRef, isSuccessRef } = useCopyToClipboard(props.value);
|
||||||
const { createMessage } = useMessage();
|
const { createMessage } = useMessage();
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
|
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
|
||||||
import { ScrollContainer } from '/@/components/Container';
|
import { ScrollContainer } from '/@/components/Container';
|
||||||
|
|
||||||
// import { useElResize } from '/@/hooks/event/useElResize';
|
|
||||||
import { propTypes } from '/@/utils/propTypes';
|
import { propTypes } from '/@/utils/propTypes';
|
||||||
import { createModalContext } from '../hooks/useModalContext';
|
import { createModalContext } from '../hooks/useModalContext';
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import { uniq } from 'lodash-es';
|
|||||||
import { getAllParentPath } from '/@/router/helper/menuHelper';
|
import { getAllParentPath } from '/@/router/helper/menuHelper';
|
||||||
|
|
||||||
import { useTimeoutFn } from '/@/hooks/core/useTimeout';
|
import { useTimeoutFn } from '/@/hooks/core/useTimeout';
|
||||||
import { useDebounce } from '/@/hooks/core/useDebounce';
|
import { useDebounceFn } from '@vueuse/core';
|
||||||
|
|
||||||
export function useOpenKeys(
|
export function useOpenKeys(
|
||||||
menuState: MenuState,
|
menuState: MenuState,
|
||||||
@ -17,7 +17,7 @@ export function useOpenKeys(
|
|||||||
mixSider: Ref<boolean>,
|
mixSider: Ref<boolean>,
|
||||||
collapse: Ref<boolean>
|
collapse: Ref<boolean>
|
||||||
) {
|
) {
|
||||||
const [debounceSetOpenKeys] = useDebounce(setOpenKeys, 50);
|
const debounceSetOpenKeys = useDebounceFn(setOpenKeys, 50);
|
||||||
async function setOpenKeys(path: string) {
|
async function setOpenKeys(path: string) {
|
||||||
const native = !mixSider.value;
|
const native = !mixSider.value;
|
||||||
const menuList = toRaw(menus.value);
|
const menuList = toRaw(menus.value);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { BasicTableProps, TableRowSelection } from '../types/table';
|
import type { BasicTableProps, TableRowSelection, BasicColumn } from '../types/table';
|
||||||
import type { Ref, ComputedRef } from 'vue';
|
import type { Ref, ComputedRef } from 'vue';
|
||||||
|
|
||||||
import { computed, unref, ref, nextTick, watch } from 'vue';
|
import { computed, unref, ref, nextTick, watch } from 'vue';
|
||||||
|
|
||||||
import { getViewportOffset } from '/@/utils/domUtils';
|
import { getViewportOffset } from '/@/utils/domUtils';
|
||||||
@ -7,9 +8,8 @@ import { isBoolean } from '/@/utils/is';
|
|||||||
|
|
||||||
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
|
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
|
||||||
import { useModalContext } from '/@/components/Modal';
|
import { useModalContext } from '/@/components/Modal';
|
||||||
import { useDebounce } from '/@/hooks/core/useDebounce';
|
|
||||||
import type { BasicColumn } from '/@/components/Table';
|
|
||||||
import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated';
|
import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated';
|
||||||
|
import { useDebounceFn } from '@vueuse/core';
|
||||||
|
|
||||||
export function useTableScroll(
|
export function useTableScroll(
|
||||||
propsRef: ComputedRef<BasicTableProps>,
|
propsRef: ComputedRef<BasicTableProps>,
|
||||||
@ -23,7 +23,7 @@ export function useTableScroll(
|
|||||||
const modalFn = useModalContext();
|
const modalFn = useModalContext();
|
||||||
|
|
||||||
// Greater than animation time 280
|
// Greater than animation time 280
|
||||||
const [debounceRedoHeight] = useDebounce(redoHeight, 100);
|
const debounceRedoHeight = useDebounceFn(redoHeight, 100);
|
||||||
|
|
||||||
const getCanResize = computed(() => {
|
const getCanResize = computed(() => {
|
||||||
const { canResize, scroll } = unref(propsRef);
|
const { canResize, scroll } = unref(propsRef);
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
import { propTypes } from '/@/utils/propTypes';
|
import { propTypes } from '/@/utils/propTypes';
|
||||||
|
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
import { useDebounce } from '/@/hooks/core/useDebounce';
|
import { useDebounceFn } from '@vueuse/core';
|
||||||
|
|
||||||
import { ToolbarEnum } from './enum';
|
import { ToolbarEnum } from './enum';
|
||||||
|
|
||||||
@ -128,7 +128,7 @@
|
|||||||
function emitChange(value?: string): void {
|
function emitChange(value?: string): void {
|
||||||
emit('search', value);
|
emit('search', value);
|
||||||
}
|
}
|
||||||
const [debounceEmitChange] = useDebounce(emitChange, 200);
|
const debounceEmitChange = useDebounceFn(emitChange, 200);
|
||||||
|
|
||||||
function handleSearch(e: ChangeEvent): void {
|
function handleSearch(e: ChangeEvent): void {
|
||||||
debounceEmitChange(e.target.value);
|
debounceEmitChange(e.target.value);
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
export const enum KeyCodeEnum {
|
|
||||||
UP = 38,
|
|
||||||
DOWN = 40,
|
|
||||||
ENTER = 13,
|
|
||||||
ESC = 27,
|
|
||||||
}
|
|
@ -29,19 +29,7 @@ export function createContext<T>(
|
|||||||
const provideData = readonly ? defineReadonly(state) : state;
|
const provideData = readonly ? defineReadonly(state) : state;
|
||||||
!createProvider && provide(key, native ? context : provideData);
|
!createProvider && provide(key, native ? context : provideData);
|
||||||
|
|
||||||
// const Provider = createProvider
|
|
||||||
// ? defineComponent({
|
|
||||||
// name: 'Provider',
|
|
||||||
// inheritAttrs: false,
|
|
||||||
// setup(_, { slots }) {
|
|
||||||
// provide(key, provideData);
|
|
||||||
// return () => slots.default?.();
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
// : null;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// Provider,
|
|
||||||
state,
|
state,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
export interface DebounceAndThrottleOptions {
|
|
||||||
// 立即执行
|
|
||||||
immediate?: boolean;
|
|
||||||
|
|
||||||
// 是否为debounce
|
|
||||||
debounce?: boolean;
|
|
||||||
// 只执行一次
|
|
||||||
once?: boolean;
|
|
||||||
}
|
|
||||||
export type CancelFn = () => void;
|
|
||||||
|
|
||||||
export type DebounceAndThrottleProcedure<T extends unknown[]> = (...args: T) => unknown;
|
|
||||||
|
|
||||||
export type DebounceAndThrottleProcedureResult<T extends unknown[]> = [
|
|
||||||
DebounceAndThrottleProcedure<T>,
|
|
||||||
CancelFn
|
|
||||||
];
|
|
||||||
|
|
||||||
import {
|
|
||||||
// throttle,
|
|
||||||
useThrottle,
|
|
||||||
} from './useThrottle';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description: Applicable in components
|
|
||||||
*/
|
|
||||||
export function useDebounce<T extends unknown[]>(
|
|
||||||
handle: DebounceAndThrottleProcedure<T>,
|
|
||||||
wait: number,
|
|
||||||
options: DebounceAndThrottleOptions = {}
|
|
||||||
): DebounceAndThrottleProcedureResult<T> {
|
|
||||||
return useThrottle(
|
|
||||||
handle,
|
|
||||||
wait,
|
|
||||||
Object.assign(options, {
|
|
||||||
debounce: true,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
export interface DebounceAndThrottleOptions {
|
|
||||||
// 立即执行
|
|
||||||
immediate?: boolean;
|
|
||||||
|
|
||||||
// 是否为debounce
|
|
||||||
debounce?: boolean;
|
|
||||||
// 只执行一次
|
|
||||||
once?: boolean;
|
|
||||||
}
|
|
||||||
export type CancelFn = () => void;
|
|
||||||
|
|
||||||
export type DebounceAndThrottleProcedure<T extends unknown[]> = (...args: T) => unknown;
|
|
||||||
|
|
||||||
export type DebounceAndThrottleProcedureResult<T extends unknown[]> = [
|
|
||||||
DebounceAndThrottleProcedure<T>,
|
|
||||||
CancelFn
|
|
||||||
];
|
|
||||||
|
|
||||||
import { isFunction } from '/@/utils/is';
|
|
||||||
export function throttle<T extends unknown[]>(
|
|
||||||
handle: DebounceAndThrottleProcedure<T>,
|
|
||||||
wait: number,
|
|
||||||
options: DebounceAndThrottleOptions = {}
|
|
||||||
): DebounceAndThrottleProcedureResult<T> {
|
|
||||||
if (!isFunction(handle)) {
|
|
||||||
throw new Error('handle is not Function!');
|
|
||||||
}
|
|
||||||
let { immediate = false } = options;
|
|
||||||
const { once = false, debounce = false } = options;
|
|
||||||
let timeoutId: Nullable<TimeoutHandle>;
|
|
||||||
// Has it been cancelled
|
|
||||||
let cancelled: boolean | null = false;
|
|
||||||
/**
|
|
||||||
* @description: clear timer
|
|
||||||
*/
|
|
||||||
function clearTimer() {
|
|
||||||
if (timeoutId) {
|
|
||||||
window.clearTimeout(timeoutId);
|
|
||||||
timeoutId = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** cancel exec */
|
|
||||||
function cancel() {
|
|
||||||
clearTimer();
|
|
||||||
cancelled = true;
|
|
||||||
}
|
|
||||||
// If once is true, only execute once
|
|
||||||
function cancelExec(): void {
|
|
||||||
once && cancel();
|
|
||||||
}
|
|
||||||
function fn(this: unknown, ...args: T) {
|
|
||||||
// If it has been cancelled, it will not be executed
|
|
||||||
if (cancelled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const exec = () => {
|
|
||||||
!debounce && clearTimer();
|
|
||||||
handle.apply(this, args);
|
|
||||||
cancelExec();
|
|
||||||
};
|
|
||||||
if (immediate) {
|
|
||||||
immediate = false;
|
|
||||||
const callNow = !timeoutId;
|
|
||||||
if (callNow) {
|
|
||||||
exec();
|
|
||||||
timeoutId = null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
debounce && clearTimer();
|
|
||||||
if (!timeoutId || debounce) {
|
|
||||||
timeoutId = setTimeout(exec, wait);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [fn, cancel];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useThrottle<T extends unknown[]>(
|
|
||||||
handle: DebounceAndThrottleProcedure<T>,
|
|
||||||
wait: number,
|
|
||||||
options: DebounceAndThrottleOptions = {}
|
|
||||||
): DebounceAndThrottleProcedureResult<T> {
|
|
||||||
return throttle(handle, wait, options);
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
import { useDebounce } from '/@/hooks/core/useDebounce';
|
|
||||||
import { addResizeListener, removeResizeListener } from '/@/utils/event';
|
|
||||||
|
|
||||||
interface WindowSizeOptions {
|
|
||||||
once?: boolean;
|
|
||||||
immediate?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useElResize<T>(
|
|
||||||
el: Element | typeof window,
|
|
||||||
fn: Fn<T>,
|
|
||||||
wait = 100,
|
|
||||||
options?: WindowSizeOptions
|
|
||||||
) {
|
|
||||||
let handler = () => {
|
|
||||||
fn();
|
|
||||||
};
|
|
||||||
const [handleSize, cancel] = useDebounce(handler, wait, options);
|
|
||||||
handler = wait ? handleSize : handler;
|
|
||||||
|
|
||||||
function start() {
|
|
||||||
addResizeListener(el, handler);
|
|
||||||
}
|
|
||||||
function stop() {
|
|
||||||
removeResizeListener(el, handler);
|
|
||||||
cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
return [start, stop];
|
|
||||||
}
|
|
@ -1,8 +1,7 @@
|
|||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
|
|
||||||
import { ref, watch, unref } from 'vue';
|
import { ref, watch, unref } from 'vue';
|
||||||
import { useDebounce } from '/@/hooks/core/useDebounce';
|
import { useThrottleFn, useDebounceFn } from '@vueuse/core';
|
||||||
import { useThrottle } from '/@/hooks/core/useThrottle';
|
|
||||||
|
|
||||||
export type RemoveEventFn = () => void;
|
export type RemoveEventFn = () => void;
|
||||||
|
|
||||||
@ -31,7 +30,7 @@ export function useEventListener({
|
|||||||
if (el) {
|
if (el) {
|
||||||
const element: Ref<Element> = ref(el as Element);
|
const element: Ref<Element> = ref(el as Element);
|
||||||
|
|
||||||
const [handler] = isDebounce ? useDebounce(listener, wait) : useThrottle(listener, wait);
|
const handler = isDebounce ? useDebounceFn(listener, wait) : useThrottleFn(listener, wait);
|
||||||
const realHandler = wait ? handler : listener;
|
const realHandler = wait ? handler : listener;
|
||||||
const removeEventListener = (e: Element) => {
|
const removeEventListener = (e: Element) => {
|
||||||
isAddRef.value = true;
|
isAddRef.value = true;
|
||||||
|
@ -1,164 +0,0 @@
|
|||||||
// https://ahooks.js.org/zh-CN/hooks/dom/use-key-press
|
|
||||||
|
|
||||||
import type { Ref } from 'vue';
|
|
||||||
import { onBeforeUnmount, onMounted, unref } from 'vue';
|
|
||||||
import { noop } from '/@/utils';
|
|
||||||
import { isFunction, isString, isNumber, isArray } from '/@/utils/is';
|
|
||||||
|
|
||||||
export type KeyPredicate = (event: KeyboardEvent) => boolean;
|
|
||||||
export type keyType = KeyboardEvent['keyCode'] | KeyboardEvent['key'];
|
|
||||||
export type KeyFilter = keyType | keyType[] | ((event: KeyboardEvent) => boolean);
|
|
||||||
export type EventHandler = (event: KeyboardEvent) => void;
|
|
||||||
|
|
||||||
export type keyEvent = 'keydown' | 'keyup';
|
|
||||||
|
|
||||||
export type TargetElement = HTMLElement | Element | Document | Window;
|
|
||||||
export type Target = Ref<TargetElement>;
|
|
||||||
|
|
||||||
export type EventOption = {
|
|
||||||
events?: keyEvent[];
|
|
||||||
target?: Target;
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultEvents: keyEvent[] = ['keydown'];
|
|
||||||
|
|
||||||
// 键盘事件 keyCode 别名
|
|
||||||
const aliasKeyCodeMap: Recordable<number | number[]> = {
|
|
||||||
esc: 27,
|
|
||||||
tab: 9,
|
|
||||||
enter: 13,
|
|
||||||
space: 32,
|
|
||||||
up: 38,
|
|
||||||
left: 37,
|
|
||||||
right: 39,
|
|
||||||
down: 40,
|
|
||||||
delete: [8, 46],
|
|
||||||
};
|
|
||||||
|
|
||||||
// 键盘事件 key 别名
|
|
||||||
const aliasKeyMap: Recordable<string | string[]> = {
|
|
||||||
esc: 'Escape',
|
|
||||||
tab: 'Tab',
|
|
||||||
enter: 'Enter',
|
|
||||||
space: ' ',
|
|
||||||
// IE11 uses key names without `Arrow` prefix for arrow keys.
|
|
||||||
up: ['Up', 'ArrowUp'],
|
|
||||||
left: ['Left', 'ArrowLeft'],
|
|
||||||
right: ['Right', 'ArrowRight'],
|
|
||||||
down: ['Down', 'ArrowDown'],
|
|
||||||
delete: ['Backspace', 'Delete'],
|
|
||||||
};
|
|
||||||
|
|
||||||
// 修饰键
|
|
||||||
const modifierKey: Recordable<(event: KeyboardEvent) => boolean> = {
|
|
||||||
ctrl: (event: KeyboardEvent) => event.ctrlKey,
|
|
||||||
shift: (event: KeyboardEvent) => event.shiftKey,
|
|
||||||
alt: (event: KeyboardEvent) => event.altKey,
|
|
||||||
meta: (event: KeyboardEvent) => event.metaKey,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断按键是否激活
|
|
||||||
* @param [event: KeyboardEvent]键盘事件
|
|
||||||
* @param [keyFilter: any] 当前键
|
|
||||||
* @returns Boolean
|
|
||||||
*/
|
|
||||||
function genFilterKey(event: any, keyFilter: any) {
|
|
||||||
// 浏览器自动补全 input 的时候,会触发 keyDown、keyUp 事件,但此时 event.key 等为空
|
|
||||||
if (!event.key) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 数字类型直接匹配事件的 keyCode
|
|
||||||
if (isNumber(keyFilter)) {
|
|
||||||
return event.keyCode === keyFilter;
|
|
||||||
}
|
|
||||||
// 字符串依次判断是否有组合键
|
|
||||||
const genArr = keyFilter.split('.');
|
|
||||||
let genLen = 0;
|
|
||||||
for (const key of genArr) {
|
|
||||||
// 组合键
|
|
||||||
const genModifier = modifierKey[key];
|
|
||||||
// key 别名
|
|
||||||
const aliasKey = aliasKeyMap[key];
|
|
||||||
// keyCode 别名
|
|
||||||
const aliasKeyCode = aliasKeyCodeMap[key];
|
|
||||||
/**
|
|
||||||
* 满足以上规则
|
|
||||||
* 1. 自定义组合键别名
|
|
||||||
* 2. 自定义 key 别名
|
|
||||||
* 3. 自定义 keyCode 别名
|
|
||||||
* 4. 匹配 key 或 keyCode
|
|
||||||
*/
|
|
||||||
if (
|
|
||||||
(genModifier && genModifier(event)) ||
|
|
||||||
(aliasKey && isArray(aliasKey) ? aliasKey.includes(event.key) : aliasKey === event.key) ||
|
|
||||||
(aliasKeyCode && isArray(aliasKeyCode)
|
|
||||||
? aliasKeyCode.includes(event.keyCode)
|
|
||||||
: aliasKeyCode === event.keyCode) ||
|
|
||||||
event.key.toUpperCase() === key.toUpperCase()
|
|
||||||
) {
|
|
||||||
genLen++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return genLen === genArr.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 键盘输入预处理方法
|
|
||||||
*/
|
|
||||||
function genKeyFormat(keyFilter: any): KeyPredicate {
|
|
||||||
if (isFunction(keyFilter)) {
|
|
||||||
return keyFilter;
|
|
||||||
}
|
|
||||||
if (isString(keyFilter) || isNumber(keyFilter)) {
|
|
||||||
return (event: KeyboardEvent) => genFilterKey(event, keyFilter);
|
|
||||||
}
|
|
||||||
if (isArray(keyFilter)) {
|
|
||||||
return (event: KeyboardEvent) => keyFilter.some((item: any) => genFilterKey(event, item));
|
|
||||||
}
|
|
||||||
return keyFilter ? () => true : () => false;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useKeyPress(
|
|
||||||
keyFilter: KeyFilter,
|
|
||||||
eventHandler: EventHandler = noop,
|
|
||||||
option: EventOption = {}
|
|
||||||
) {
|
|
||||||
const { events = defaultEvents, target } = option;
|
|
||||||
|
|
||||||
let el: TargetElement | null | undefined;
|
|
||||||
|
|
||||||
function handler(event: any) {
|
|
||||||
const genGuard: KeyPredicate = genKeyFormat(keyFilter);
|
|
||||||
if (genGuard(event)) {
|
|
||||||
return eventHandler(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
el = getTargetElement(target, window);
|
|
||||||
if (!el) return;
|
|
||||||
|
|
||||||
for (const eventName of events) {
|
|
||||||
el.addEventListener(eventName, handler);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
if (!el) return;
|
|
||||||
for (const eventName of events) {
|
|
||||||
el.removeEventListener(eventName, handler);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getTargetElement(
|
|
||||||
target?: Target,
|
|
||||||
defaultElement?: TargetElement
|
|
||||||
): TargetElement | undefined | null {
|
|
||||||
if (!target) {
|
|
||||||
return defaultElement;
|
|
||||||
}
|
|
||||||
return isFunction(target) ? target() : unref(target);
|
|
||||||
}
|
|
@ -1,8 +1,8 @@
|
|||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
|
|
||||||
import { ref, onMounted, watch, onUnmounted } from 'vue';
|
import { ref, onMounted, watch, onUnmounted } from 'vue';
|
||||||
import { useThrottle } from '/@/hooks/core/useThrottle';
|
|
||||||
import { isWindow, isObject } from '/@/utils/is';
|
import { isWindow, isObject } from '/@/utils/is';
|
||||||
|
import { useThrottleFn } from '@vueuse/core';
|
||||||
|
|
||||||
export function useScroll(
|
export function useScroll(
|
||||||
refEl: Ref<Element | Window | null>,
|
refEl: Ref<Element | Window | null>,
|
||||||
@ -31,8 +31,7 @@ export function useScroll(
|
|||||||
Reflect.deleteProperty(options, 'wait');
|
Reflect.deleteProperty(options, 'wait');
|
||||||
}
|
}
|
||||||
|
|
||||||
const [throttleHandle] = useThrottle(handler, wait);
|
handler = useThrottleFn(handler, wait);
|
||||||
handler = throttleHandle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let stopWatch: () => void;
|
let stopWatch: () => void;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { tryOnMounted, tryOnUnmounted } from '@vueuse/core';
|
import { tryOnMounted, tryOnUnmounted } from '@vueuse/core';
|
||||||
import { useDebounce } from '/@/hooks/core/useDebounce';
|
import { useDebounceFn } from '@vueuse/core';
|
||||||
|
|
||||||
interface WindowSizeOptions {
|
interface WindowSizeOptions {
|
||||||
once?: boolean;
|
once?: boolean;
|
||||||
@ -11,7 +11,7 @@ export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOp
|
|||||||
let handler = () => {
|
let handler = () => {
|
||||||
fn();
|
fn();
|
||||||
};
|
};
|
||||||
const [handleSize, cancel] = useDebounce(handler, wait, options);
|
const handleSize = useDebounceFn(handler, wait);
|
||||||
handler = handleSize;
|
handler = handleSize;
|
||||||
|
|
||||||
const start = () => {
|
const start = () => {
|
||||||
@ -23,7 +23,6 @@ export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOp
|
|||||||
|
|
||||||
const stop = () => {
|
const stop = () => {
|
||||||
window.removeEventListener('resize', handler);
|
window.removeEventListener('resize', handler);
|
||||||
cancel();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tryOnMounted(() => {
|
tryOnMounted(() => {
|
||||||
|
@ -4,7 +4,7 @@ import type { Ref } from 'vue';
|
|||||||
import { useTimeoutFn } from '/@/hooks/core/useTimeout';
|
import { useTimeoutFn } from '/@/hooks/core/useTimeout';
|
||||||
import { tryOnUnmounted } from '@vueuse/core';
|
import { tryOnUnmounted } from '@vueuse/core';
|
||||||
import { unref, nextTick, watch, computed, ref } from 'vue';
|
import { unref, nextTick, watch, computed, ref } from 'vue';
|
||||||
import { useDebounce } from '/@/hooks/core/useDebounce';
|
import { useDebounceFn } from '@vueuse/core';
|
||||||
import { useEventListener } from '/@/hooks/event/useEventListener';
|
import { useEventListener } from '/@/hooks/event/useEventListener';
|
||||||
import { useBreakpoint } from '/@/hooks/event/useBreakpoint';
|
import { useBreakpoint } from '/@/hooks/event/useBreakpoint';
|
||||||
|
|
||||||
@ -21,8 +21,7 @@ export function useECharts(
|
|||||||
const cacheOptions = ref<EChartsOption>({});
|
const cacheOptions = ref<EChartsOption>({});
|
||||||
let removeResizeFn: Fn = () => {};
|
let removeResizeFn: Fn = () => {};
|
||||||
|
|
||||||
const [debounceResize] = useDebounce(resize, 200);
|
resizeFn = useDebounceFn(resize, 200);
|
||||||
resizeFn = debounceResize;
|
|
||||||
|
|
||||||
const getOptions = computed(
|
const getOptions = computed(
|
||||||
(): EChartsOption => {
|
(): EChartsOption => {
|
||||||
|
@ -2,13 +2,14 @@ import { computed, unref } from 'vue';
|
|||||||
|
|
||||||
import { useAppStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
|
|
||||||
import router from '/@/router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description: Full screen display content
|
* @description: Full screen display content
|
||||||
*/
|
*/
|
||||||
export const useFullContent = () => {
|
export const useFullContent = () => {
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
|
const router = useRouter();
|
||||||
const { currentRoute } = router;
|
const { currentRoute } = router;
|
||||||
|
|
||||||
// Whether to display the content in full screen without displaying the menu
|
// Whether to display the content in full screen without displaying the menu
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { computed, onUnmounted, unref, watchEffect } from 'vue';
|
import { computed, onUnmounted, unref, watchEffect } from 'vue';
|
||||||
import { useThrottle } from '/@/hooks/core/useThrottle';
|
import { useThrottleFn } from '@vueuse/core';
|
||||||
|
|
||||||
import { useAppStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
import { useLockStore } from '/@/store/modules/lock';
|
import { useLockStore } from '/@/store/modules/lock';
|
||||||
@ -59,7 +59,7 @@ export function useLockPage() {
|
|||||||
clear();
|
clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
const [keyupFn] = useThrottle(resetCalcLockTimeout, 2000);
|
const keyupFn = useThrottleFn(resetCalcLockTimeout, 2000);
|
||||||
|
|
||||||
return computed(() => {
|
return computed(() => {
|
||||||
if (unref(getLockTime)) {
|
if (unref(getLockTime)) {
|
||||||
|
@ -94,6 +94,7 @@ export function usePermission() {
|
|||||||
'Please switch PermissionModeEnum to ROLE mode in the configuration to operate!'
|
'Please switch PermissionModeEnum to ROLE mode in the configuration to operate!'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isArray(roles)) {
|
if (!isArray(roles)) {
|
||||||
roles = [roles];
|
roles = [roles];
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import { watch, unref, ref, computed } from 'vue';
|
|||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
import { MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
import { MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
||||||
import { useThrottle } from '/@/hooks/core/useThrottle';
|
import { useThrottleFn } from '@vueuse/core';
|
||||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||||
|
|
||||||
import { getChildrenMenus, getCurrentParentPath, getMenus, getShallowMenus } from '/@/router/menus';
|
import { getChildrenMenus, getCurrentParentPath, getMenus, getShallowMenus } from '/@/router/menus';
|
||||||
@ -20,7 +20,7 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
|
|||||||
const permissionStore = usePermissionStore();
|
const permissionStore = usePermissionStore();
|
||||||
const { setMenuSetting, getIsHorizontal, getSplit } = useMenuSetting();
|
const { setMenuSetting, getIsHorizontal, getSplit } = useMenuSetting();
|
||||||
|
|
||||||
const [throttleHandleSplitLeftMenu] = useThrottle(handleSplitLeftMenu, 50);
|
const throttleHandleSplitLeftMenu = useThrottleFn(handleSplitLeftMenu, 50);
|
||||||
|
|
||||||
const splitNotLeft = computed(
|
const splitNotLeft = computed(
|
||||||
() => unref(splitType) !== MenuSplitTyeEnum.LEFT && !unref(getIsHorizontal)
|
() => unref(splitType) !== MenuSplitTyeEnum.LEFT && !unref(getIsHorizontal)
|
||||||
|
@ -5,7 +5,7 @@ import { computed, unref, onMounted, nextTick, ref } from 'vue';
|
|||||||
import { TriggerEnum } from '/@/enums/menuEnum';
|
import { TriggerEnum } from '/@/enums/menuEnum';
|
||||||
|
|
||||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||||
import { useDebounce } from '/@/hooks/core/useDebounce';
|
import { useDebounceFn } from '@vueuse/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle related operations of menu events
|
* Handle related operations of menu events
|
||||||
@ -64,7 +64,7 @@ export function useDragLine(siderRef: Ref<any>, dragBarRef: Ref<any>, mix = fals
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const [exec] = useDebounce(changeWrapWidth, 80);
|
const exec = useDebounceFn(changeWrapWidth, 80);
|
||||||
exec();
|
exec();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -88,8 +88,7 @@
|
|||||||
import { useUserStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin';
|
import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { useKeyPress } from '/@/hooks/event/useKeyPress';
|
import { onKeyStroke } from '@vueuse/core';
|
||||||
import { KeyCodeEnum } from '/@/enums/keyCodeEnum';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'LoginForm',
|
name: 'LoginForm',
|
||||||
@ -129,13 +128,8 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { validForm } = useFormValid(formRef);
|
const { validForm } = useFormValid(formRef);
|
||||||
useKeyPress(['enter'], (events) => {
|
|
||||||
const keyCode = events.keyCode;
|
|
||||||
|
|
||||||
if (keyCode === KeyCodeEnum.ENTER) {
|
onKeyStroke('Enter', handleLogin);
|
||||||
handleLogin();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN);
|
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user