getBoundingClientRect
import type { FunctionArgs } from '@vueuse/core'; import { upperFirst } from 'lodash-es'; \ export interface ViewportOffsetResult { left: number; top: number; right: number; bottom: number; rightIncludeBody: number; bottomIncludeBody: number; } \ export function getBoundingClientRect(element: Element): DOMRect | number { if (!element || !element.getBoundingClientRect) { return 0; } return element.getBoundingClientRect(); }
trim
function trim(string: string) { return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, ''); }
hasClass
/* istanbul ignore next */ export function hasClass(el: Element, cls: string) { if (!el || !cls) return false; if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.'); if (el.classList) { return el.classList.contains(cls); } else { return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1; } }
addClass
/* istanbul ignore next */ export function addClass(el: Element, cls: string) { if (!el) return; let curClass = el.className; const classes = (cls || '').split(' '); \ for (let i = 0, j = classes.length; i < j; i++) { const clsName = classes[i]; if (!clsName) continue; \ if (el.classList) { el.classList.add(clsName); } else if (!hasClass(el, clsName)) { curClass += ' ' + clsName; } } if (!el.classList) { el.className = curClass; } }
removeClass
/* istanbul ignore next */ export function removeClass(el: Element, cls: string) { if (!el || !cls) return; const classes = cls.split(' '); let curClass = ' ' + el.className + ' '; \ for (let i = 0, j = classes.length; i < j; i++) { const clsName = classes[i]; if (!clsName) continue; \ if (el.classList) { el.classList.remove(clsName); } else if (hasClass(el, clsName)) { curClass = curClass.replace(' ' + clsName + ' ', ' '); } } if (!el.classList) { el.className = trim(curClass); } }
getViewportOffset
/** * Get the left and top offset of the current element * left: the distance between the leftmost element and the left side of the document * top: the distance from the top of the element to the top of the document * right: the distance from the far right of the element to the right of the document * bottom: the distance from the bottom of the element to the bottom of the document * rightIncludeBody: the distance between the leftmost element and the right side of the document * bottomIncludeBody: the distance from the bottom of the element to the bottom of the document * * @description: */ export function getViewportOffset(element: Element): ViewportOffsetResult { const doc = document.documentElement; \ const docScrollLeft = doc.scrollLeft; const docScrollTop = doc.scrollTop; const docClientLeft = doc.clientLeft; const docClientTop = doc.clientTop; \ const pageXOffset = window.pageXOffset; const pageYOffset = window.pageYOffset; \ const box = getBoundingClientRect(element); \ const { left: retLeft, top: rectTop, width: rectWidth, height: rectHeight } = box as DOMRect; \ const scrollLeft = (pageXOffset || docScrollLeft) - (docClientLeft || 0); const scrollTop = (pageYOffset || docScrollTop) - (docClientTop || 0); const offsetLeft = retLeft + pageXOffset; const offsetTop = rectTop + pageYOffset; \ const left = offsetLeft - scrollLeft; const top = offsetTop - scrollTop; \ const clientWidth = window.document.documentElement.clientWidth; const clientHeight = window.document.documentElement.clientHeight; return { left: left, top: top, right: clientWidth - rectWidth - left, bottom: clientHeight - rectHeight - top, rightIncludeBody: clientWidth - left, bottomIncludeBody: clientHeight - top, }; }
hackCss
export function hackCss(attr: string, value: string) { const prefix: string[] = ['webkit', 'Moz', 'ms', 'OT']; \ const styleObj: any = {}; prefix.forEach((item) => { styleObj[`${item}${upperFirst(attr)}`] = value; }); return { ...styleObj, [attr]: value, }; }
on
/* istanbul ignore next */ export function on( element: Element | HTMLElement | Document | Window, event: string, handler: EventListenerOrEventListenerObject ): void { if (element && event && handler) { element.addEventListener(event, handler, false); } }
off
/* istanbul ignore next */ export function off( element: Element | HTMLElement | Document | Window, event: string, handler: Fn ): void { if (element && event && handler) { element.removeEventListener(event, handler, false); } }
once
/* istanbul ignore next */ export function once(el: HTMLElement, event: string, fn: EventListener): void { const listener = function (this: any, ...args: unknown[]) { if (fn) { fn.apply(this, args); } off(el, event, listener); }; on(el, event, listener); }
useRafThrottle
export function useRafThrottle<T extends FunctionArgs>(fn: T): T { let locked = false; // @ts-ignore return function (...args: any[]) { if (locked) return; locked = true; window.requestAnimationFrame(() => { // @ts-ignore fn.apply(this, args); locked = false; }); }; }
getEnv
/** * @description: Get environment variables * @returns: * @example: */ export function getEnv(): string { return import.meta.env.MODE; }
isDevMode
/** * @description: Is it a development mode * @returns: * @example: */ export function isDevMode(): boolean { return import.meta.env.DEV; }
isProdMode
/** * @description: Is it a production mode * @returns: * @example: */ export function isProdMode(): boolean { return import.meta.env.PROD; }
setObjToUrlParams
/** * Add the object as a parameter to the URL * @param baseUrl url * @param obj * @returns {string} * eg: * let obj = {a: '3', b: '4'} * setObjToUrlParams('www.baidu.com', obj) * ==>www.baidu.com?a=3&b=4 */ export function setObjToUrlParams(baseUrl: string, obj: any): string { let parameters = ''; for (const key in obj) { parameters += key + '=' + encodeURIComponent(obj[key]) + '&'; } parameters = parameters.replace(/&$/, ''); return /\?$/.test(baseUrl) ? baseUrl + parameters : baseUrl.replace(/\/?$/, '?') + parameters; }
deepMerge
export function deepMerge<T = any>(src: any = {}, target: any = {}): T { let key: string; for (key in target) { src[key] = isObject(src[key]) ? deepMerge(src[key], target[key]) : (src[key] = target[key]); } return src; }
openWindow
export function openWindow( url: string, opt?: { target?: TargetContext | string; noopener?: boolean; noreferrer?: boolean } ) { const { target = '__blank', noopener = true, noreferrer = true } = opt || {}; const feature: string[] = []; \ noopener && feature.push('noopener=yes'); noreferrer && feature.push('noreferrer=yes'); \ window.open(url, target, feature.join(',')); }
getDynamicProps
// dynamic use hook props export function getDynamicProps<T, U>(props: T): Partial<U> { const ret: Recordable = {}; \ Object.keys(props).map((key) => { ret[key] = unref((props as Recordable)[key]); }); \ return ret as Partial<U>; }
getRawRoute
export function getRawRoute(route: RouteLocationNormalized): RouteLocationNormalized { if (!route) return route; const { matched, ...opt } = route; return { ...opt, matched: (matched ? matched.map((item) => ({ meta: item.meta, name: item.name, path: item.path, })) : undefined) as RouteRecordNormalized[], }; }
is
const toString = Object.prototype.toString; \ export function is(val: unknown, type: string) { return toString.call(val) === `[object ${type}]`; }
isDef
export function isDef<T = unknown>(val?: T): val is T { return typeof val !== 'undefined'; }
isUnDef
export function isUnDef<T = unknown>(val?: T): val is T { return !isDef(val); }
isObject
export function isObject(val: any): val is Record<any, any> { return val !== null && is(val, 'Object'); }
isEmpty
export function isEmpty<T = unknown>(val: T): val is T { if (isArray(val) || isString(val)) { return val.length === 0; } \ if (val instanceof Map || val instanceof Set) { return val.size === 0; } \ if (isObject(val)) { return Object.keys(val).length === 0; } \ return false; }
isDate
export function isDate(val: unknown): val is Date { return is(val, 'Date'); }
isNull
export function isNull(val: unknown): val is null { return val === null; }
isNullAndUnDef
export function isNullAndUnDef(val: unknown): val is null | undefined { return isUnDef(val) && isNull(val); }
isNullOrUnDef
export function isNullOrUnDef(val: unknown): val is null | undefined { return isUnDef(val) || isNull(val); }
isNumber
export function isNumber(val: unknown): val is number { return is(val, 'Number'); }
isPromise
export function isPromise<T = any>(val: unknown): val is Promise<T> { return is(val, 'Promise') && isObject(val) && isFunction(val.then) && isFunction(val.catch); }
isString
export function isString(val: unknown): val is string { return is(val, 'String'); }
isFunction
export function isFunction(val: unknown): val is Function { return typeof val === 'function'; }
isBoolean
export function isBoolean(val: unknown): val is boolean { return is(val, 'Boolean'); }
isRegExp
export function isRegExp(val: unknown): val is RegExp { return is(val, 'RegExp'); }
isArray
export function isArray(val: any): val is Array<any> { return val && Array.isArray(val); }
isWindow
export function isWindow(val: any): val is Window { return typeof window !== 'undefined' && is(val, 'Window'); }
isElement
export function isElement(val: unknown): val is Element { return isObject(val) && !!val.tagName; }
isMap
export function isMap(val: unknown): val is Map<any, any> { return is(val, 'Map'); }
isUrl
export const isServer = typeof window === 'undefined'; \ export const isClient = !isServer; \ export function isUrl(path: string): boolean { const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/; return reg.test(path); }
buildUUID
\ const hexList: string[] = []; for (let i = 0; i <= 15; i++) { hexList[i] = i.toString(16); } \ export function buildUUID(): string { let uuid = ''; for (let i = 1; i <= 36; i++) { if (i === 9 || i === 14 || i === 19 || i === 24) { uuid += '-'; } else if (i === 15) { uuid += 4; } else if (i === 20) { uuid += hexList[(Math.random() * 4) | 8]; } else { uuid += hexList[(Math.random() * 16) | 0]; } } return uuid.replace(/-/g, ''); }
buildShortUUID
let unique = 0; export function buildShortUUID(prefix = ''): string { const time = Date.now(); const random = Math.floor(Math.random() * 1000000000); unique++; return prefix + '_' + random + unique + String(time); }
9 公共接口请求
defHttp 可以直接查看axios.ts文件。
import { defHttp } from '/@/utils/http/axios'; import { GetAccountInfoModel } from './model/accountModel'; enum Api { ACCOUNT_INFO = '/account/getAccountInfo', SESSION_TIMEOUT = '/user/sessionTimeout', } // Get personal center-basic settings export const accountInfoApi = () => defHttp.get<GetAccountInfoModel>({ url: Api.ACCOUNT_INFO }); export const sessionTimeoutApi = () => defHttp.post<void>({ url: Api.SESSION_TIMEOUT });
10 常用函数
// Cancel event async function onClose(e: Recordable) { const { closeFunc } = unref(getProps); emit('close', e); if (closeFunc && isFunction(closeFunc)) { const res = await closeFunc(); visibleRef.value = !res; return; } visibleRef.value = false; }
watch( () => visibleRef.value, (visible) => { nextTick(() => { emit('visible-change', visible); instance && drawerInstance.emitVisible?.(visible, instance.uid); }); } );