前端新手Vue3+Vite+Ts+Pinia+Sass项目指北系列文章 —— 第十二章 常用工具函数 (Utils配置)

前言

在项目开发中,我们经常会使用一些工具函数,也经常会用到例如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')
    return

  document.onkeydown = (e) => {
    const ev: KeyboardEventInit = e || window.event
    const keyCode = ev.code || ev.keyCode
    if (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 null

  const format = pattern || '{y}-{m}-{d}'
  let date
  if (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 * 1000

    date = 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})+(?:$|\.))/g
  num = 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 = value
  document.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 = null
  return (...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 = href
  downloadElement.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项目指北系列文章已经全部更新完了,感谢各位小伙伴的支持与厚爱,文章中可能有一些依赖部分会有所更新,最后依赖版本号请参考仓库中的地址进行对照。前端道路道阻且长,富而杂,多而繁,请各位取长补短,各自努力绽放。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/395025.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于JAVA+SpringBoot+Vue的前后端分离的电影院售票管理运营平台

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 该系统研究背景聚焦于…

【日常聊聊】深度学习进度

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 方向一&#xff1a;深度学习的基本原理和算法 方向二&#xff1a;深度学习的应用实例 方向三&#xff1a;深度学习的挑战和未…

vue3项目引入本地js文件,实现一个音频播放按钮

目前有一个需求就是在网页上放置一个音乐控制按钮&#xff0c;并且是在vue3项目里面。于是小白的我遇到了2个问题&#xff0c;第一个问题是如何实现没有进度条的播放按钮&#xff0c;这个网上有现成的代码&#xff0c;可以通过js代码切换不同的图片或者是别的样式&#xff0c;并…

【c语言】c语言转义字符详解

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;c语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&…

【千帆平台】使用千帆大模型平台创建自定义模型调用API,贺岁灵感模型,文本对话

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是《千帆平台》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和…

html的表单标签(上):form标签和input标签

表单标签 表单是让用户输入信息的重要途径。 用表单标签来完成与服务器的一次交互&#xff0c;比如你登录QQ账号时的场景。 表单分成两个部分&#xff1a; 表单域&#xff1a;包含表单元素的区域&#xff0c;用form标签来表示。表单控件&#xff1a;输入框&#xff0c;提交按…

黑马程序员-瑞吉外卖day9

菜品分类下拉列表 CategoryController里面写 /*** 根据条件查询分类数据** param category* return*/GetMapping("/list")ApiOperation("菜品分类目录")public R<List<Category>> list(Category category) {List<Category> list cate…

改进Rust与C++的互操作性,谷歌向 Rust 基金会捐赠100万美元

hello宝子们...我们是艾斯视觉擅长ui设计和前端开发10年经验&#xff01;希望我的分享能帮助到您&#xff01;如需帮助可以评论关注私信我们一起探讨&#xff01;致敬感谢感恩&#xff01; 标题&#xff1a;谷歌向 Rust 基金会捐赠 100 万美元&#xff0c;致力于提升 Rust 与 C…

【plt.pie绘制饼图】:从入门到精通,只需一篇文章!【Matplotlib可视化】

【&#x1f4ca;plt.pie绘制饼图】&#xff1a;从入门到精通&#xff0c;只需一篇文章&#xff01;【Matplotlib可视化】&#xff01; 利用Matplotlib进行数据可视化示例 &#x1f335;文章目录&#x1f335; &#x1f3a8; 一、饼图初探&#xff1a;基本概念与用途&#x1f4a…

Zookeeper未授权访问漏洞

Zookeeper漏洞介绍 Zookeeper支持某些特定的四字查询命令&#xff0c;可以未授权访问&#xff0c;从而泄露zookeeper服务的相关信息&#xff0c;这些信息可能作为进一步入侵其他系统和服务的跳板&#xff0c;利用这些信息实现权限提升并逐渐扩大攻击范围。 常见的四字命令有 e…

作为一个程序员,最少要看过这几部电影吧?

计算机专业必看的几部电影 计算机专业必看的几部电影&#xff0c;就像一场精彩的编程盛宴&#xff01;《黑客帝国》让你穿越虚拟世界&#xff0c;感受高科技的魅力&#xff1b;《社交网络》揭示了互联网巨头的创业之路&#xff0c;《源代码》带你穿越时间解救世界&#xff0c;…

佳能2580的下载手册

凡是和电子产品有关的产品其内部都开始不断地进行内卷&#xff0c;在不断地内卷背后&#xff0c;意味着科技更新和换代&#xff0c;自己也入手了一台佳能2580的打印机&#xff0c;一台相对比较老式的打印机&#xff0c;以此不断地自己想要进行打印的需要。 下载的基础步骤&…

【办公类-16-07-01】“2023下学期 周计划-美术专用活动室写法”(python 排班表系列)

背景需求&#xff1a; 又到了开学季&#xff0c;新的活动室安排表出炉了。 为了贴在美术活动室的安排表&#xff0c;我需要转换成班级为单位的安排表&#xff0c;便于批量制作周计划。 最终效果&#xff1a; 第五、六、七、八、十七、十八周“快乐玩色彩”专用活动室。 重点说…

希尔排序算法

目录 ShellSort希尔排序 整体思路 图解分析 【1】预排序 单组排序 多组并排 【2】直接插入排序 关于gap取值 总代码实现 时间复杂度 ShellSort希尔排序 希尔排序法又称缩小增量法。 希尔排序法的基本思想是&#xff1a;先选定一个整数&#xff0c;把待排序文件中所有…

[力扣 Hot100]Day29 删除链表的倒数第 N 个结点

题目描述 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 出处 思路 两个指针间隔n&#xff0c;一趟遍历解决。 代码 class Solution { public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode* phead;ListNode* …

计算机网络基础入门指南

文章目录 网络分层模型OSI七层模型及其作用TCP/IP四层模型及作用为什么网络需要分层&#xff1f; 常见的网络协议应用层常见的协议传输层常见的协议网络层常见协议 从输入URL到页面展示的过程HTTP常见的状态码HTTP与HTTPS的区别HTTP是不保存状态的协议&#xff0c;如何保存用户…

激光条纹中心线提取算法FPGA实现方案

1 概述 激光条纹中心线提取是3D线激光测量领域一个较为基础且重要的算法。目前&#xff0c;激光条纹中心线提取已有多种成熟的算法&#xff0c;有很多相关的博客和论文。 激光条纹中心线提取的真实意义在于工程化和产品化的实际应用&#xff0c;而很多算法目前只能用于学术研究…

(五)【Jmeter】使用代理录制HTTP脚本操作步骤及注意事项

前置信息 软件版本Jmeter5.6.3服务网址备注drupalhttp://192.168.88.88:18080/(二)【Jmeter】专栏实战项目靶场drupal部署 用户名密码test1test1test2test2实操记录 1、启动jmeter,操作顺序见下图 2、在视图面板添加如下信息,点击开始

简单一招,教你高校管理校园门禁!

在当今社会&#xff0c;随着城市化和科技的不断发展&#xff0c;人们对安全管理的需求日益增加。门禁监控系统作为一种现代化、智能化的安全管理工具&#xff0c;正逐渐成为各种场所的必备设施。 客户案例 企业办公大楼 北京某大型企业在其办公大楼部署了泛地缘科技推出的门禁…

PyCharm - Script parameters (脚本参数)

PyCharm - Script parameters [脚本参数] References Run -> Edit Configurations… -> Run/Debug Configurations -> Configuration -> Script parameters 命令行&#xff1a; python display_yolo_log.py ./person_training_log/person_train_log_DIMM40_stdout…