当前位置: 首页 > ds >正文

关于前端常用的部分公共方法(二)

1.读取json文件内容

/*** 读取JSON文件内容* * @template T 返回的数据类型* @param {File} file 文件选择框选择的文件对象* @returns {Promise<T>} 解析后的JSON数据*/
export function readJSON<T>(file: File): Promise<T> {return new Promise((resolve, reject) => {const fileName = file.name;const fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();if (fileExtension !== "json") {reject(new Error("文件类型不合法,请选择JSON格式文件!"));return;}if (window.FileReader) {const reader = new FileReader();reader.readAsText(file, "UTF-8");reader.onload = () => {try {resolve(JSON.parse(reader.result as string));} catch (error) {reject(new Error("解析JSON文件失败"));}};reader.onerror = () => {reject(new Error("读取文件失败"));};}});
}

代码改进点

  1. 参数类型从any改为明确的File类型,提升类型安全性
  2. 添加错误处理逻辑,使用reject返回错误状态
  3. 优化变量命名,fileType改为更准确的fileExtension
  4. 添加try-catch处理JSON解析可能出现的异常
  5. 添加文件读取错误的处理逻辑

使用示例

const fileInput = document.getElementById('file-input') as HTMLInputElement;
fileInput.addEventListener('change', async (event) => {const file = event.target.files?.[0];if (!file) return;try {const data = await readJSON<MyDataType>(file);console.log(data);} catch (error) {console.error(error.message);}
});

2. 判断是否 "经度,纬度" 字符串值

以下是实现判断字符串是否为"经度,纬度"格式的TypeScript代码:

/*** 判断是否 "经度,纬度" 字符串值** @export* @param {string} text 传入的字符串* @return {boolean} 是否 经度,纬度*/
export function isLonLat(text: string): boolean {const reg = /^-?((0|1?[0-7]?[0-9]?)(([.][0-9]*)?)|180(([.][0]*)?)),-?((0|[1-8]?[0-9]?)(([.][0-9]*)?)|90(([.][0]*)?))$/return reg.test(text)
}

该正则表达式解析:

  • 经度部分:-?((0|1?[0-7]?[0-9]?)(([.][0-9]*)?)|180(([.][0]*)?))

    • 允许负号开头
    • 0-179度,可选小数部分
    • 或180度整数(可选.0结尾)
  • 纬度部分:-?((0|[1-8]?[0-9]?)(([.][0-9]*)?)|90(([.][0]*)?))

    • 允许负号开头
    • 0-89度,可选小数部分
    • 或90度整数(可选.0结尾)
  • 经度纬度用逗号分隔

3. 获取URL参数

/*** 获取URL参数** @export* @param {string} parameter url参数名* @return {string | null} 参数值*/
export function getQueryString(parameter: string): string | null {return new URL(window.location.href).searchParams.get(parameter)
}

函数说明: 该函数使用现代URL API解析当前页面URL的查询参数,比传统字符串分割方法更可靠。参数说明:

  • parameter: 需要获取的URL参数名称
  • 返回值: 参数值字符串,若不存在则返回null

使用示例:

// 假设当前URL为 https://example.com?name=test&id=123
const name = getQueryString('name') // 返回 'test'
const age = getQueryString('age') // 返回 null

注意事项:

  • 需要浏览器支持URL接口(所有现代浏览器均支持)
  • 返回的字符串不会被自动解码,如需解码URI组件需额外处理
  • 参数名称区分大小写

4. 将指定的异步方法转为Promise

/*** 将指定的异步方法转为Promise* * @param {*} context* @param {string} apiName* @param {string} [success="success"]* @param {string} [error="error"]* @return {*} Promise*/
export function apiToSync(context: any, apiName: string, success = "success", error = "error") {return new Promise((resolve, reject) => {context[apiName]({[success]: (res: any) => resolve(res),[error]: (err: any) => reject(err)})})
}
/*** 将多个异步方法转为Promise数组* * @param {*} context* @param {string[]} apiNames* @param {string} [success="success"]* @param {string} [error="error"]* @return {*} Promise[]*/
export function apiArrayToSync(context: any, apiNames: string[], success = "success", error = "error") {return apiNames.map(apiName => apiToSync(context, apiName, success, error))
}

代码实现了以下功能:

  • apiToSync函数将单个异步API转换为Promise
  • apiArrayToSync函数批量转换多个API为Promise数组
  • 支持自定义成功和失败的回调字段名
  • 保留了原始API的context调用方式
  • 类型标注使用TypeScript语法

5. 将指定的多个异步方法转为Promise

/*** 将指定的多个异步方法转为Promise** @param {*} context* @param {string[]} apiNames* @param {string} [success="success"]* @param {string} [error="error"]* @return {*} Promise[]*/
export function apiArrayToSync(context: any, apiNames: string[], success = "success", error = "error") {return apiNames.map((name) => {const apiFunc = context[name]return (options: any) =>new Promise((resolve, reject) => {options[success] = function (result: any) {resolve(result)}options[error] = function (error) {reject(error)}apiFunc.call(context, options)})})
}

使用方法

// 假设有一个对象包含异步API方法
const apiObject = {asyncApi1(options: any) {setTimeout(() => {options.success('Result from asyncApi1')}, 1000)},asyncApi2(options: any) {setTimeout(() => {options.success('Result from asyncApi2')}, 500)}
}// 转换为Promise数组
const promiseArray = apiArrayToSync(apiObject, ['asyncApi1', 'asyncApi2'])// 使用Promise.all并行调用
Promise.all([promiseArray[0]({}),promiseArray[1]({})
]).then(results => {console.log(results) // ['Result from asyncApi1', 'Result from asyncApi2']
}).catch(error => {console.error(error)
})

关键点说明

  • 该函数将基于回调的异步方法转换为Promise形式
  • 支持自定义成功和失败的回调键名
  • 返回的是Promise数组,可以配合Promise.all使用
  • 保持了原始方法的this绑定

参数说明

  • context: 包含异步方法的对象
  • apiNames: 需要转换的方法名数组
  • success: 成功回调的键名,默认为'success'
  • error: 失败回调的键名,默认为'error'

6. 单个权限验证

/*** 单个权限验证* @param value 权限值* @returns 有权限,返回 `true`,反之则反*/
export function auth(value: string): boolean {const stores = useUserInfo();return stores.userInfos.authBtnList.some((v: string) => v === value);
}

7. 多个权限验证,满足一个则为true

/*** 多个权限验证,满足一个则为 true* @param value 权限值* @returns 有权限,返回 `true`,反之则反*/
export function auths(value: Array<string>): boolean {let flag = false;const stores = useUserInfo();stores.userInfos.authBtnList.map((val: string) => {value.map((v: string) => {if (val === v) flag = true;});});return flag;
}

8.  多个权限验证,全部满足则为 true

/*** 多个权限验证,全部满足则为 true* @param value 权限值* @returns 有权限,返回 `true`,反之则反*/
export function authAll(value: Array<string>): boolean {const stores = useUserInfo();return judementSameArr(value, stores.userInfos.authBtnList);
}/*** 判断两数组字符串是否相同(用于按钮权限验证),数组字符串中存在相同时会自动去重(按钮权限标识不会重复)* @param news 新数据* @param old 源数据* @returns 两数组相同返回 `true`,反之则反*/
export function judementSameArr(newArr: unknown[] | string[], oldArr: string[]): boolean {const news = removeDuplicate(newArr);const olds = removeDuplicate(oldArr);let count = 0;const leng = news.length;for (let i in olds) {for (let j in news) {if (olds[i] === news[j]) count++;}}return count === leng ? true : false;
}

9.  获取UI框架图片URL

/*** 获取UI框架图片URL* @param name 图片名称* @param prefix 前置根路径*/
export function getImageUrl(name: string | unknown, prefix = 'frame') {return new URL(`/src/assets/images/${prefix}/${name}.png`, import.meta.url).href;
}/*** 获取业务图片URL* @param name 图片名称*/
export function getBaseImage(name: string | unknown) {return new URL(`/src/assets/images/${name}.png`, import.meta.url).href;
}/*** 获取IConURL* @param name 图标名称*/
export function getIconUrl(name: string | unknown) {return new URL(`/src/assets/icons/${name}.png`, import.meta.url).href;
}

10.  转换秒单位为X小时X分钟X秒的格式

/*** 转换秒单位为X小时X分钟X秒的格式* @returns {String}*/
export function transSeconds(rawSeconds: number) {if (rawSeconds && rawSeconds > 0) {let last = 0;const hours = Math.floor(rawSeconds / 3600);last = rawSeconds - hours * 3600;const minute = parseInt(Math.floor(last / 60).toString());const seconds = parseInt((rawSeconds - hours * 3600 - minute * 60).toString());return `${hours > 0 ? hours + '小时' : ''}${minute}分${seconds}秒`;}return '';
}

11. 输入框限制只能输入数字,并且范围为0-999

<el-input clearable maxlength="3" v-model.number="form.warningthresholdmin" @input="validateMinValue"></el-input>// 输入框限制输入只能输入正整数,并且不能大于999
const validateMinValue = (value: any) => {// 将输入值转换为数字let num = Number(value);if (!value) {form.warningthresholdmin = '';return;}// 检查输入值是否是数字if (isNaN(num)) {// 如果不是数字,将其设置为空字符串form.warningthresholdmin = '';return;}// 检查输入值是否在 0 到 999 的范围内if (num < 0) {num = 0;} else if (num > 999) {num = 999;}// 更新输入框的值form.warningthresholdmin = num;}

12. 输入框限制只能输入数字,支持小数,小数点前四位,小数点后六位(经纬度输入框)

 <el-input placeholder="请输入经度" maxlength="10" @input="e => handleInput(e,'longitude')" clearable v-model="form.longitude"></el-input>
<el-input placeholder="请输入纬度" maxlength="10" @input="e => handleInput(e, 'latitude')" clearable v-model="form.latitude"></el-input>// 限制经纬度输入只能输入数字0-9999.999999
const handleInput = (value: any, type: string) => {// 处理空值if (!value) {if (type === "latitude") {form.latitude = '';} else {form.longitude = '';}return;}let val = value.toString();// 非法输入,限制范围或清空if (val === '.') {// 允许小数点开头,后续通过正则处理if (type === "latitude") {form.latitude = '0.';} else {form.longitude = '0.';}} else {// 移除非法字符val = val.replace(/[^0-9\.]/g, '');val = val.replace(/(\..*)\./g, '$1'); // 只允许一个小数点// 限制小数点后六位const parts = val.split('.');if (parts.length > 1 && parts[1].length > 6) {parts[1] = parts[1].substring(0, 6);val = parts.join('.');}// 转换为数字并限制范围let num = parseFloat(val);let number = val;// 检查输入值是否是数字if (isNaN(num)) {// 如果不是数字,将其设置为空字符串if (type === "latitude") {form.latitude = '';} else {form.longitude = '';}return;}// 检查输入值是否在 0 到 999 的范围内if (number < 0) {number = 0;} else if (number > 9999.999999) {number = 9999.999999;}if (type === "latitude") {form.latitude = number;} else {form.longitude = number;}}
}
http://www.xdnf.cn/news/13350.html

相关文章:

  • 2.6 查看动态库或程序的依赖库
  • PH热榜 | 2025-06-06
  • 高保真组件库:上传
  • “深时数字地球”新进展!科学智能助推地球科学研究范式变革
  • if综合演练——石头剪刀布
  • 命令行关闭Windows防火墙
  • 网络爬虫解析技术与实战代码详解
  • 可编程光子处理器新范式:《APL Photonics》封面级成果展示多功能集成突破
  • 报文口令重写功能分析(以某巢为例)
  • 一款 AI 驱动的 Wiki 知识库
  • python中的闭包
  • 安装和使用G4F(GPT4Free) 最新0.5.3.2 版本
  • 算法从0到1 Day 17 二叉树part 06
  • Linux 关键目录解析:底层机制与技术细节
  • 从制造出海到智造全球,艾芬达如何拥抱工业互联网革命?
  • Sass具有超能力的CSS预处理器
  • 【leetcode】136. 只出现一次的数字
  • RAG质量评估
  • Spacy词性对照表
  • 位运算总结
  • 博科Brocade FC交换机常用操作命令
  • 【Vue】scoped+组件通信+props校验
  • istio流量管理问题
  • 2.3 物理层设备
  • python load/loads dump/dumps的区别
  • Web 前端性能优化全景指南与实战策略
  • 何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡
  • 2025-06-09 java面试总结
  • 新基建浪潮下:中国新能源汽车充电桩智慧化建设与管理实践
  • CC攻击与WAF的对抗战