前言
在项目开发中,我们经常会使用一些工具函数,也经常会用到例如loadsh
等工具库,但是这些工具库的体积往往比较大,如果项目本身已经引入了这些工具库,那么我们就没有必要再引入一次,所以我们需要自己封装一些工具函数,来简化我们的开发。
一、通用类工具函数
在
src/utils
目录下创建tools
文件夹,用于存放通用类工具函数文件。
在tools
文件下创建index.ts
文件
import { ElMessage, MessageHandler } from 'element-plus'/*** @description 文档注册enter事件* @param {Function} cb* @return {void}*/
export function handleEnter(cb: Function): void {if (typeof cb !== 'function')returndocument.onkeydown = (e) => {const ev: KeyboardEventInit = e || window.eventconst keyCode = ev.code || ev.keyCodeif (keyCode === 'Enter' || keyCode === 13)cb()}
}/*** @description 日期格式化* @param {string | number} time {string like:{y}-{m}-{d} {h}:{i}:{s} } pattern* @return {string}*/
export function parseTime(time: string | number, pattern: string) {if (arguments.length === 0 || !time)return nullconst format = pattern || '{y}-{m}-{d}'let dateif (typeof time === 'object') {date = time}else {if (typeof time === 'string' && /^[0-9]+$/.test(time)) {time = Number.parseInt(time)}else if (typeof time === 'string') {time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '')}if (typeof time === 'number' && time.toString().length === 10)time = time * 1000date = new Date(time)}const formatObj: Record<string, string> = {y: date.getFullYear(), // 年m: date.getMonth() + 1, // 月d: date.getDate(), // 日h: date.getHours(), // 时i: date.getMinutes(), // 分s: date.getSeconds(), // 秒a: date.getDay(), // 星期几}const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {let value = formatObj[key]// 注意:getDay()返回的是0表示星期天if (key === 'a')return ['日', '一', '二', '三', '四', '五', '六'][value]if (result.length > 0 && Number(value) < 10)value = `0${value}`return value || 0})return time_str
}/*** @description trim函数* @param {string} str* @return {string}*/
export function trim(str: string): string {return str.replace(/^\s+|\s+$/g, '') // 去除字符串两端的空格
}/*** @description uuid的生成* @return {string}*/
/*** @description 生成UUID* @return {string}*/
export function getUUID(): string {const s: string[] = []const hexDigits = '0123456789abcdef'for (let i = 0; i < 36; i++) {s[i] = hexDigits[Math.floor(Math.random() * 0x10)]}s[14] = '4's[19] = hexDigits[(parseInt(s[19], 16) & 0x3) | 0x8]s[8] = s[13] = s[18] = s[23] = '-'const uuid = s.join('')return uuid
}
// 38673f6b-bacc-4d9b-9330-dd97b7ae238f/*** @description 千分位* @param {string | number} num* @return {void}*/
export function addThousand(num: string | number): string {if (num)num = Number(num).toFixed(2)if ((!num && num !== 0) || num == 'NaN')return '--'const regForm = /(\d{1,3})(?=(\d{3})+(?:$|\.))/gnum = num.toString().replace(regForm, '$1,')return num
}/*** @description 大数值转换和保留n位有效数字* @param {number} num {number} digits* @return {string}*/
export function numberFormatter(num: number, digits: number | undefined): string {const si = [{ value: 1e13, symbol: '亿亿' },{ value: 1e12, symbol: '万亿' },{ value: 1e11, symbol: '千亿' },{ value: 1e10, symbol: '百亿' },{ value: 1e9, symbol: '十亿' },{ value: 1e8, symbol: '亿' },{ value: 1e7, symbol: '千万' },{ value: 1e6, symbol: '百万' },{ value: 1e5, symbol: '十万' },{ value: 1e4, symbol: '万' },{ value: 1e3, symbol: '千' },]for (let i = 0; i < si.length; i++) {if (num >= si[i].value)return (num / si[i].value).toFixed(digits).replace(/\.0+$|(\.[0-9]*[1-9])0+$/, '$1') + si[i].symbol}return num.toString()
}/*** @description 复制方法* @param {string} value 传入要复制的值* @return {string | MessageHandler}*/
export const copy = (value: string): string | MessageHandler => {if (!value)return ElMessage.error('复制失败')const tag = document.createElement('textarea')tag.value = valuedocument.body.appendChild(tag)tag.select()document.execCommand('copy')ElMessage.success('复制成功')tag.remove()return value
}/*** @description 防抖* @param {number} timer* @return {function}*/
export function debounce(timer = 0): (callback: unknown, delay: number) => void {return (callback: unknown, delay: number) => {if (timer)clearTimeout(timer)if (typeof callback === 'function')timer = setTimeout(callback, delay)}
}/*** @description 节流* @param {number} timer* @return {function}*/
export const throttle: (fn: (...args: unknown[]) => void, timer: number) => (...args: unknown[]) => void = (fn, timer = 0) => {let time: number | null = nullreturn (...args: unknown[]) => {if (time)clearTimeout(time)time = setTimeout(() => {fn.apply(this, args)}, timer)}
}
二、文件相关函数
在
tools
文件下创建blobType.ts
文件
export const blobType: Record<string, string> = {'aac': 'image/audio/aac','abw': 'application/x-abiword','arc': 'application/x-freearc','avi': 'video/x-msvideo','azw': 'application/vnd.amazon.ebook','bin': 'application/octet-stream','bmp': 'image/bmp','bz': 'application/x-bzip','bz2': 'application/x-bzip2','csh': 'application/x-csh','css': 'text/css','csv': 'text/csv','doc': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document','docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document','eot': 'application/vnd.ms-fontobject','epub': 'application/epub+zip','exe': 'application/x-msdownload','gif': 'image/gif','htm': 'text/html','html': 'text/html','ico': 'image/vnd.microsoft.icon','ics': 'text/calendar','jar': 'application/java-archive','jpeg': 'image/jpeg','jpg': 'image/jpeg','js': 'text/javascript','json': 'application/json','jsonld': 'application/ld+json','mid': 'audio/midi audio/x-midi','midi': 'audio/midi audio/x-midi','mjs': 'text/javascript','mp3': 'audio/mpeg','mpeg': 'video/mpeg','mpkg': 'application/vnd.apple.installer+xml','odp': 'application/vnd.oasis.opendocument.presentation','ods': 'application/vnd.oasis.opendocument.spreadsheet','odt': 'application/vnd.oasis.opendocument.text','oga': 'audio/ogg','ogv': 'video/ogg','ogx': 'application/ogg','otf': 'font/otf','png': 'image/png','pdf': 'application/pdf','ppt': 'application/vnd.ms-powerpoint','pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation','rar': 'application/x-rar-compressed','rtf': 'application/rtf','sh': 'ima','svg': 'image/svg+xml','swf': 'application/x-shockwave-flash','tar': 'application/x-tar','tif': 'image/tiff','tiff': 'image/tiff','ttf': 'font/ttf','txt': 'text/plain','vsd': 'application/vnd.visio','wav': 'audio/wav','weba': 'audio/webm','webm': 'video/webm','webp': 'image/webp','woff': 'font/woff','woff2': 'font/woff2','xhtml': 'application/xhtml+xml','xls': 'application/vnd.ms-excel','xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet','xml': 'text/xml','xul': 'application/vnd.mozilla.xul+xml','zip': 'application/zip','3gp': 'video/3gpp','3g2': 'video/3gpp2','7z': 'application/x-7z-compressed',
}
在
tools
文件下创建file.ts
文件
import { ElMessage } from 'element-plus'
import { blobType } from './blobType'export function download(file: any, fileType: string, fileName?: string) {if (!fileName) {const timeStr = new Date().getTime()fileName = `${timeStr}`}const type = formatFileType(fileType)if (!type)return ElMessage.warning('暂不支持此格式!')const blob = new Blob([file], { type })const downloadElement = document.createElement('a')const href = window.URL.createObjectURL(blob) // 创建下载的链接downloadElement.href = hrefdownloadElement.download = fileName // 下载后文件名document.body.appendChild(downloadElement)downloadElement.click() // 点击下载document.body.removeChild(downloadElement) // 下载完成移除元素window.URL.revokeObjectURL(href) // 释放掉blob对象
}export function formatFileType(fileFormat: string) {return blobType[fileFormat]
}export function blobToFileReader(blob: any, callback: any) {if (!blob.size)return ElMessage.warning('暂无资源!')if (blob.type !== 'application/json')return callback(blob)const fr: any = new FileReader()fr.onloadend = function () {try {callback(JSON.parse(fr.result))}catch (err) {ElMessage.warning('资源数据有误!')}}fr.readAsText(blob)
}
三、存储相关函数
在
src/utils
目录下创建cache
文件夹,用于存放存储类工具函数文件。
在cache
文件夹下创建index.ts
文件
/*** window.localStorage 浏览器永久缓存* @method set 设置永久缓存* @method get 获取永久缓存* @method remove 移除永久缓存* @method clear 移除全部永久缓存*/
export const Local = {// 设置永久缓存set(key: string, val: any) {window.localStorage.setItem(key, JSON.stringify(val))},// 获取永久缓存get(key: string) {const json: any = window.localStorage.getItem(key)return JSON.parse(json)},// 移除永久缓存remove(key: string) {window.localStorage.removeItem(key)},// 移除全部永久缓存clear() {window.localStorage.clear()},
}/*** window.sessionStorage 浏览器临时缓存* @method set 设置临时缓存* @method get 获取临时缓存* @method remove 移除临时缓存* @method clear 移除全部临时缓存*/
export const Session = {// 设置临时缓存set(key: string, val: any) {window.sessionStorage.setItem(key, JSON.stringify(val))},// 获取临时缓存get(key: string) {const json: any = window.sessionStorage.getItem(key)return JSON.parse(json)},// 移除临时缓存remove(key: string) {window.sessionStorage.removeItem(key)},// 移除全部临时缓存clear() {window.sessionStorage.clear()},
}
总结
工具函数的封装,可以提高代码的复用性,降低维护成本,本文只是介绍了一小部分工具函数的封装,更多的工具函数的封装,可以参考lodash等函数工具库,也可以根据实际需求,封装自己的工具函数。上文中的配置代码可在 github
仓库中直接 copy
,仓库路径:https://github.com/SmallTeddy/ProjectConstructionHub。
写在最后
经过一段时间的整理和书写,前端新手Vue3+Vite+Ts+Pinia+Sass项目指北系列文章已经全部更新完了,感谢各位小伙伴的支持与厚爱,文章中可能有一些依赖部分会有所更新,最后依赖版本号请参考仓库中的地址进行对照。前端道路道阻且长,富而杂,多而繁,请各位取长补短,各自努力绽放。