UNPKG

ivue-material-plus

Version:

A high quality UI components Library with Vue.js

402 lines (318 loc) • 8.97 kB
import { CSSProperties, computed, ref } from 'vue'; import { isDef, isNumeric } from './validate'; // 文件上传类型 export type UploaderResultType = 'dataUrl' | 'text' | 'file' | 'url'; export type Interceptor = (...args: any[]) => Promise<boolean> | boolean; export type UploaderMaxSize = number | string | ((file: File) => boolean); export type UploaderFileListItem = { url?: string; file?: File; content?: string; status?: '' | 'uploading' | 'done' | 'failed'; message?: string; beforeDelete?: Interceptor; }; // 读取文件内容 export function readFileContent(file: File, resultType: UploaderResultType) { return new Promise<string | void>((resolve) => { // 文件类型 if (resultType === 'file') { resolve(); return; } // url if (resultType === 'url') { const url = URL.createObjectURL(file); resolve(url); return; } const reader = new FileReader(); reader.onload = (event) => { resolve((event.target as FileReader).result as string); }; // base64 if (resultType === 'dataUrl') { reader.readAsDataURL(file); } // 文本类型 else if (resultType === 'text') { reader.readAsText(file); } }); } // 文件是否超出大小 export function isOversize( items: UploaderFileListItem | UploaderFileListItem[], maxSize: UploaderMaxSize ): boolean { return toArray(items).some((item) => { if (item.file) { if (isFunction(maxSize)) { return maxSize(item.file); } return item.file.size > maxSize; } return false; }); } // 设置为数组 export function toArray<T>(item: T | T[]): T[] { if (Array.isArray(item)) { return item; } return [item]; } // 是否是方法 // eslint-disable-next-line @typescript-eslint/ban-types export function isFunction(val: unknown): val is Function { return typeof val === 'function'; } // 过滤文件 export function filterFiles( items: UploaderFileListItem[], maxSize: UploaderMaxSize ) { const valid: UploaderFileListItem[] = []; const invalid: UploaderFileListItem[] = []; items.forEach((item) => { if (isOversize(item, maxSize)) { invalid.push(item); } else { valid.push(item); } }); return { valid, invalid }; } // 设置随机字符串 export const getRandomStr = (len = 32) => { const $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; const length = $chars.length; let str = ''; for (let i = 0; i < len; i++) { str += $chars.charAt(Math.floor(Math.random() * length)); } return str; }; const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i; export function isImageUrl(url: string): boolean { return IMAGE_REGEXP.test(url); } // 是图片 export function isImageFile(item): boolean { // some special urls cannot be recognized // user can add `isImage` flag to mark it as an image url if (item.isImage) { return true; } // 文件类型 if (item.file && item.file.type) { return item.file.type.indexOf('image') === 0; } // 有链接 if (item.url) { return isImageUrl(item.url); } // base64 if (typeof item.content === 'string') { return item.content.indexOf('data:image') === 0; } return false; } export function addUnit(value?: string | number): string | undefined { if (!isDef(value)) { return undefined; } return isNumeric(value) ? `${value}px` : String(value); } // 获取大小样式 export function getSizeStyle( originSize?: string | number ): CSSProperties | undefined { if (isDef(originSize)) { const size = addUnit(originSize); return { width: size, height: size, }; } } // 事件代码 export const EVENT_CODE = { tab: 'Tab', enter: 'Enter', space: 'Space', left: 'ArrowLeft', // 37 up: 'ArrowUp', // 38 right: 'ArrowRight', // 39 down: 'ArrowDown', // 40 esc: 'Escape', delete: 'Delete', backspace: 'Backspace', }; // 创建数组范围 export function createRange(length) { return Array.from({ length }, (v, k) => k); } // 是否是颜色 export function isCssColor(color) { return !!color && !!color.match(/^(#|(rgb|hsl)a?\()/); } // 设置文字颜色 export function setTextColor(color: string | string[]) { let style: { color?: string; } = {}; // 是否是数组 if (Array.isArray(color)) { style = { color: `${color[0]}`, }; } else if (isCssColor(color)) { style = { color: `${color}`, }; } else if (color) { const [colorName] = color.toString().trim().split(' ', 2); style = { color: `${colorName}--text`, }; } return style; } // 是否是纯数字 export function isValueNumber(value) { return /^[0-9][0-9]*$/.test(value + ''); } // 已经获取滚动条宽度 let cached; // 获取滚动条宽度 export function getScrollBarSize(fresh?) { if (!isClient) { return 0; } if (fresh || cached === undefined) { const inner = document.createElement('div'); inner.style.width = '100%'; inner.style.height = '200px'; const outer = document.createElement('div'); const outerStyle: CSSStyleDeclaration = outer.style; outerStyle.position = 'absolute'; outerStyle.top = '0px'; outerStyle.left = '0px'; outerStyle.pointerEvents = 'none'; outerStyle.visibility = 'hidden'; outerStyle.width = '200px'; outerStyle.height = '150px'; outerStyle.overflow = 'hidden'; outer.appendChild(inner); document.body.appendChild(outer); const widthContained = inner.offsetWidth; outer.style.overflow = 'scroll'; let widthScroll = inner.offsetWidth; if (widthContained === widthScroll) { widthScroll = outer.clientWidth; } document.body.removeChild(outer); cached = widthContained - widthScroll; } return cached; } const zIndex = ref(0); // 创建zindex export const useZIndex = () => { const currentZIndex = computed(() => 2000 + zIndex.value); // 下一个数值 const nextZIndex = () => { zIndex.value++; return currentZIndex.value; }; return { currentZIndex, nextZIndex, }; }; // 是否是客户端 export const isClient = typeof window !== 'undefined'; // 是否是对象 export const isObject = (obj: unknown): boolean => { return obj !== null && typeof obj === 'object'; }; // 是否是Element export const isElement = (el: HTMLElement) => { return typeof HTMLElement === 'object' && el instanceof HTMLElement; }; // 下载文件 export async function downloadFile(url, name = '') { if (!isClient) { return Promise.reject(); } try { const res = await fetch(url); const blob = await res.blob(); const split = res.url.split('/'); // 文件名称 const fileName = split[split.length - 1]; if (!blob) { return Promise.reject(); } const localUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.setAttribute('href', localUrl); a.setAttribute('download', name || fileName); a.click(); URL.revokeObjectURL(localUrl); return Promise.resolve(); } catch (e) { return Promise.reject(e); } } // requestAnimationFrame export function raf(fn: FrameRequestCallback): number { return isClient ? requestAnimationFrame(fn) : -1; } // cancelAnimationFrame export function cancelRaf(id: number) { if (isClient) { cancelAnimationFrame(id); } } // double raf for animation export function doubleRaf(fn: FrameRequestCallback): void { raf(() => raf(fn)); } // 是否是undefined export const isUndefined = (val: any): val is undefined => val === undefined; // Find components upward export function findComponentsUpward(context, componentName) { const parents = []; const parent = context.$parent; if (parent) { // 找到当前组件名称 if (parent.$options.name === componentName) { parents.push(parent); } // 拼接数组 return parents.concat(findComponentsUpward(parent, componentName)); } else { return []; } } // Find components upward export function findComponentUpward(context, componentName, componentNames?) { // 当前组件名称 if (typeof componentName === 'string') { componentNames = [componentName]; } else { componentNames = componentName; } let parent = context.$parent; let name = parent.$options.name; while (parent && (!name || componentNames.indexOf(name) < 0)) { parent = parent.$parent; if (parent) { name = parent.$options.name; } } return parent; }