跳转到内容

❧ 实用的代码段大全

获取URL参数

// 代码:
const getURLParameters = url => (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce((a, v) => ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a), {});
// 案例:
getURLParameters('http://url.com/page?name=Adam&surname=Smith');
// {name: 'Adam', surname: 'Smith'}

无限极分类树形结构

// 代码:
const toTree = (data) => {
// 删除所有 children,以防止多次调用
data.forEach(function (item) {
delete item.children
})
// 以id为key的map索引数据列
const map = {}
data.forEach(function (item) {
map[item.value] = item
})
const val = []
data.forEach(function (item) {
const parent = map[item.pid]
// 自身放入对应的父节点下
if (parent) {
(parent.children || (parent.children = [])).push(item)
} else {
// 顶级节点
val.push(item)
}
})
return val
}
// 案例:
toTree([{id:1001,pid:1002,name:'Apple'}, ...])

导出csv文件

// 代码:
function exportCsv(csv, filename = 'export.csv') {
const BOM = '\uFEFF';
const blob = new Blob([BOM + csv], { type: 'text/csv;charset=utf-8;' });
if (navigator.msSaveOrOpenBlob) {
navigator.msSaveOrOpenBlob(blob, filename);
} else {
const downloadLink = document.createElement('a');
downloadLink.href = URL.createObjectURL(blob);
downloadLink.download = filename;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}
}
// 案例:
exportCsv('"field1","field2"', '文件名.csv');

列表多字段、多排序类型

// 代码:
/**
* list Array 数据列表
* fields string[] 排序字段
* order string|string[] 排序类型, asc/desc
*/
const listSort = (list, fields, order) => {
const fieldsLen = fields.length;
if (Object.prototype.toString.call(order) == '[object Array]' && order.length != fieldsLen) {
throw new Error("字段数组和排序类型数组长度必须一直");
}
// 根据排序类型获取最终结果
const getResult = (result, orderType) => {
return orderType == 'desc' ? -result : result;
}
// 排序处理
const dealSort = (data, fields, index) => {
const orderType = Object.prototype.toString.call(order) == '[object Array]' ? order[index] : order;
const { left, right } = data;
const field = fields[index];
const isString = typeof left[field] == 'string' && typeof right[field] == 'string';
if (index == fieldsLen - 1) {
return getResult(isString ? left[field].localeCompare(right[field], 'zh-CN') : left[field] - right[field], orderType);
} else {
if (left[field] == right[field]) {
return dealSort(data, fields, index + 1);
}
return getResult(isString ? left[field].localeCompare(right[field], 'zh-CN') : left[field] - right[field], orderType);
}
}
return list.sort((left, right) => {
return dealSort({ left, right }, fields, 0);
})
}
// 案例:
listSort(list, ['name', 'age'], 'asc');
listSort(list, ['name', 'age'], ['asc', 'desc']);

数字格式化展示,包含小数位数限定、百分数、千分位等

/**
* 数字格式化展示,包含小数位数限定、百分数、千分位等
* https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString
* @param num number 数值
* @param options.style string 样式类型,decimal|currency|percent
* @param options.maximumFractionDigits number 最多保留小数位数
* @param options.useGrouping number 是否使用千分位
* @return string
*/
const numFormat = (num, options = {}) => {
const {style, maximumFractionDigits, useGrouping} = options;
const newOptions = {style: style ?? 'decimal', maximumFractionDigits: maximumFractionDigits ?? 2};
if (useGrouping === false) {
newOptions.useGrouping = false;
}
return num.toLocaleString('zh-CN', newOptions);
}

树结构数据筛选过滤

// 树结构数据筛选过滤
const matchTreeData = (arr: {[key: string]: any}[], keyword: string, fields: string[]) => {
const newArr: {[key: string]: any}[] = [];
arr.forEach((item: {[key: string]: any}) => {
for (const field of fields) {
if (!item.hasOwnProperty(field)) {
continue;
}
if (item[field] && item[field].indexOf(keyword) !== -1) {
newArr.push(item);
break;
} else {
const children = matchTreeData(item.children || [], keyword, fields);
if (children.length > 0) {
newArr.push({ ...item, children })
break;
}
}
}
})
return newArr;
}

文件大小格式化显示

const formatFileSize = (size: number) => {
const value = Number(size);
if (size && !isNaN(value)) {
const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB', 'BB'];
let index = 0;
let k = value;
if (value >= 1024) {
while (k > 1024) {
k = k / 1024;
index++;
}
}
return `${(k).toFixed(1)}${units[index]}`;
}
return '-';
}

在线文件下载

const getBlob = (url: string, cb: Function) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "blob";
xhr.onload = function () {
if (xhr.status === 200) {
cb(xhr.response);
}
};
xhr.send();
}
const saveAs = (blob: Blob, filename: string) => {
const link = document.createElement("a");
const body = document.querySelector("body") as HTMLBodyElement;
link.href = window.URL.createObjectURL(blob);
link.download = filename;
// fix Firefox
link.style.display = "none";
body.appendChild(link);
link.click();
body.removeChild(link);
window.URL.revokeObjectURL(link.href);
}
const download = (url: string, filename: string) => {
getBlob(url, function (blob: Blob) {
saveAs(blob, filename);
});
}

ElementUI表单获取焦点提示填写

/**
* ElementUI表单获取焦点提示填写
*
* @param {HTMLElement} dom 元素节点
* @param {string} type input 或 textarea
*/
const elementFocus = (dom: HTMLElement, type: 'input'|'textarea') => {
if (!dom || !['input', 'textarea'].includes(type)) {
return;
}
const element = dom.getElementsByClassName(`el-${type}__inner`)[0] as HTMLElement;
element.focus();
}
/* Vue3使用 */
// 初始化定义
const instance = getCurrentInstance() as ComponentInternalInstance;
// 校验处处理
const refs: {[key: string]: any} = instance.refs;
elementFocus(refs['domRef'].$el, 'input');

判断是否为移动端

const isMobile = () => {
const userAgent = navigator.userAgent.toLowerCase();
const device = /ipad|iphone|midp|rv:1.2.3.4|ucweb|android|windows ce|windows mobile/;//可以在这里补充
return device.test(userAgent);
}

列表页搜索过滤分页

/**
* 列表页搜索过滤分页
* @param list 数据列表
* @param options.pager 分页配置
* @param options.keyword 搜索关键词
* @param options.fields 搜索字段
* @param options.filterHook 自定义过滤条件
* @param options.mergeField 根据此合并字段进行分页
* @returns Array
*/
type ListSearchOptions = {
pager?: { page: number, size: number, total: number },
keyword?: string,
fields?: string[],
mergeField?: string,
filterHook?: Function,
}
const pageListSearch = (list: {[key: string]: any}[], options: ListSearchOptions = {}) => {
const { pager, keyword, fields, filterHook, mergeField } = options;
if ((keyword && fields) || filterHook) {
list = list.filter((t: {[key: string]: any}) => {
let status = false;
if (keyword && fields) {
const kw = keyword.toLowerCase();
for (const field of fields) {
status = status || t[field]?.toLowerCase()?.includes(kw)
}
}
if (filterHook) {
status = status || filterHook(t);
}
return status;
});
}
if (!pager) { return list; }
if (mergeField) {
const ids: number[] = [];
const idMap: {[key: string]: boolean} = {};
let count = 0;
list.forEach((item: {[key: string]: any}) => {
if (!idMap[item[mergeField]]) {
count++;
ids.push(item[mergeField]);
idMap[item[mergeField]] = true;
}
item.index = count;
});
pager.total = ids.length;
if (pager.page > Math.ceil(pager.total/pager.size)) {
pager.page = 1;
}
const start = (pager.page - 1) * pager.size;
const end = start + pager.size;
const newIds = ids.slice(start, end);
const newIdMap = {};
for (const id of newIds) {
newIdMap[id] = true;
}
const newList = list.filter((t: {[key: string]: any}) => newIdMap[t[mergeField]]);
return newList;
}
pager.total = list.length;
if (pager.page > Math.ceil(pager.total/pager.size)) {
pager.page = 1;
}
const start = (pager.page - 1) * pager.size;
const end = start + pager.size;
return list.slice(start, end);
}