在闲余的时间整理一份我们可能用到的前端工具库方法。
export function getQueryStringByStr(data) {
const url = data; // 获取url中"?"符后的字串
const theRequest = {};
if (url.indexOf('?') !== -1) {
const str = url.substr(1);
const strs = str.split('&');
for (let i = 0; i < strs.length; i += 1) {
theRequest[strs[i].split('=')[0]] = unescape(strs[i].split('=')[1]);
}
}
return theRequest;
}
/**
* @param {Object} props
* @description 针对搜索值做统一处理
*/
export function convertParams(props) {
const newParams = {};
for (const index in props) {
const item = props[index];
const type = typeof item;
if (item && type === 'string') {
newParams[index] = item.replace(/\s/g, '');
} if (Object.prototype.toString.call(item) === '[object Object]') {
newParams[index] = convertParams(item)
} else {
newParams[index] = item;
}
}
return newParams;
};
/**
* @param {Array|String} target 目标数组
* @param {Boolean} boolean 是否开启与的关系
* @description 判断当前用户是否在权限数据中
*/
export const authority = (target, boolean = false) => {
const str = getProps('authority') // 获取当前角色的所有权限码, 自定义获取;
if (Array.isArray(target)) {
if (boolean) {
return target.every(item => roles.indexOf(item) > -1)
}
return target.some(item => roles.indexOf(item) > -1)
}
return str && str.indexOf(target) > -1
}
/**
* 菜单栏权限显示隐藏/现在很多架构都是自动化路由,有现成的权限配置
* @param {Array} list 通过路由列表得到菜单列表
* @returns {Array}
* @description 通过用户权限控制的菜单列表(简易版)
*/
export const hasChild = (item) => {
return item.children && item.children.length !== 0
}
export const getMenuByAside = (list) => {
let res = [];
list.forEach(item => {
if (!item.access || authority(item.access)) {
let obj = {
title: item.title,
index: item.index,
icon: item.icon,
access: item.access || undefined,
}
if (hasChild(item)) obj.children = getMenuByAside(item.children)
if (hasChild(item) && authority(item.access)) {
obj.children = getMenuByAside(item.children)
}
res.push(obj)
}
})
return res
}
/**
* @param {Array} target 目标数组
* @param {String} key 目标key值
* @param {Boolean} boolean 是否需要数组转换
* @param {Object} option 匹配的对象key值,值:label/value/boolean
* @return {Array}
* @description 处理二维数组转一维数组匹配相关字段值
*/
export const reduceConcat = (target, key, boolean, option) => {
let newTarget = [];
const { label, bool, value } = option || {};
newTarget = target && target.map(item => {
if (boolean) {
return item[key] && item[key].map(opt => ({
...item,
[key]: opt,
[label]: bool ? item[label][value] : item[label]
}))
}
return item[key];
}
).reduce((a, b) => a.concat(b));
return newTarget || [];
}
// 转换时间(时分秒)
/**
* @param {Number|String} msd 转换时间戳
* @description 将时间戳转换成时分秒
*/
export function dealTimeToText(value) {
let time = Math.floor(value / 1000)
let h = Math.floor(Math.floor(time / 60) / 60)
let min = Math.floor(time / 60) % 60
let s = Math.round(time % 3600 % 60)
if (h > 0) {
return `${h}h${min}min${s}s`
} else if (min > 0) {
return `${min}min${s}s`
} else {
return `${s}s`
}
}
/**
* @param {Number|String} value
* @description 秒数转化为时分秒
*/
export const formatSeconds = (value) => {
let secondTime = parseInt(value), minuteTime = 0, hourTime = 0;
if (secondTime > 60) {
minuteTime = parseInt(secondTime / 60);
secondTime = parseInt(secondTime % 60);
if (minuteTime > 60) {
hourTime = parseInt(minuteTime / 60);
minuteTime = parseInt(minuteTime % 60);
}
}
let result = "" + parseInt(secondTime) + "秒";
if (minuteTime > 0) {
result = "" + parseInt(minuteTime) + "分" + result;
}
if (hourTime > 0) {
result = "" + parseInt(hourTime) + "小时" + result;
}
return result;
}
/**
* @param {String} dateTime 接收的日期eg: 1994-03-2 || 1569404854000
* @description 通用年龄计算公式
* */
import moment from 'moment';
export const getAgeYear = (dateTime) => {
let reg = /^(\d{4})-(\d{1,2})-(\d{1,2})$/
let time = !reg.test(dateTime) ? moment(dateTime, 'YYYY-MM-DD') : dateTime;
let regexp = time.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/);
if (!regexp) return '';
let date = new Date(regexp[1], regexp[3] - 1, regexp[4]);
if (date.getFullYear() == regexp[1] && (date.getMonth() + 1) == regexp[3]
&& date.getDate() == regexp[4]) {
let year = new Date().getFullYear();
return year - regexp[1];
}
}
// 组件渲染后,500毫秒改变一次组件颜色
componentDidMount() {
this.interval = setInterval(this.getRandomColor, 500);
}
getRandomColor = () => {
this.setState({
col: '#'+('00000'+(Math.random()*0x1000000<<0).toString(16)).slice(-6),
});
}
/**
* @param {str} 用户需要显示的水印信息
* @description 背景水印
* */
export function addWaterMarker(str) {
const can = document.createElement('canvas');
// const { body } = document;
// body.appendChild(can);
can.width = 200;
can.height = 100;
can.style.display = 'none';
const cans = can.getContext('2d');
cans.rotate(20 * Math.PI / 180);
cans.font = '16px Microsoft JhengHei';
cans.fillStyle = 'rgba(17, 17, 17, 0.50)';
cans.textAlign = 'left';
cans.textBaseline = 'Middle';
cans.fillText(str, can.width / 3, can.height / 2);
return `url(${can.toDataURL('image/png')})`;
}
/**
* url转base64
*/
urlToBase64(url) {
return new Promise((resolve, reject) => {
let canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d"),
img = new Image();
img.crossOrigin = "Anonymous";
img.src = url;
img.onload = () => {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
let dataUrl = canvas.toDataURL("image/jpeg");
canvas = null;
resolve(dataUrl);
};
});
},
const codeMessage = {
200: '服务器成功返回请求的数据。',
201: '新建或修改数据成功。',
202: '一个请求已经进入后台排队(异步任务)。',
204: '删除数据成功。',
400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
401: '用户没有权限(令牌、用户名、密码错误)。',
403: '用户得到授权,但是访问是被禁止的。',
404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
406: '请求的格式不可得。',
410: '请求的资源被永久删除,且不会再得到的。',
422: '当创建一个对象时,发生一个验证错误。',
500: '服务器发生错误,请检查服务器。',
502: '网关错误。',
503: '服务不可用,服务器暂时过载或维护。',
504: '网关超时。',
};
/**
* @param {String} url 下载URL地址
* @param {String|Number} downloadName 下载文件名称
* @Parma {type} 下载请求方法get||post
* @description 导出Excel文件
* */
import Vue from 'vue';
import moment from 'moment';
import Cookies from "js-cookie";
const that = new Vue();
export function fileDownload(url, downloadName = moment(new Date(), 'YYYY-MM-DD') + "任务监控数据表", option) {
const { type, status, message, messageErr, params } = option;
let fileName = downloadName + '.xlsx';
let request = new XMLHttpRequest();
status ? that.$message({
type: 'warning',
showClose: true,
message: message || '已点击正在下载,请稍后...',
}) : null;
request.open(type || 'GET', url, true);
request.setRequestHeader("Authorization", Cookies.get("user-token"));
request.setRequestHeader(
"Content-Type",
params ? 'application/json' : "application/x-www-form-urlencoded; charset=UTF-8"
);
request.responseType = "blob";
request.onload = function () {
if (this.status === 200) {
let blob = this.response;
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveBlob(blob, fileName);
} else {
let downloadLink = document.createElement("a");
let contentTypeHeader = request.getResponseHeader("Content-Type");
downloadLink.href = window.URL.createObjectURL(
new Blob([blob], { type: contentTypeHeader })
);
downloadLink.download = fileName;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
window.URL.revokeObjectURL(downloadLink.href)
}
} else {
that.$message({
type: 'error',
showClose: true,
message: messageErr ||'文件下载失败...',
});
}
};
request.send(params ? JSON.stringify(params) : void null);
}
const toDataUrl = (blob) => {
return new Promise(resolve => {
let file = new FileReader();
file.onload = event => {
resolve(event.target.result);
};
file.readAsDataURL(blob);
});
},
export const Base64 = {
//加密
encode(params) {
return btoa(encodeURIComponent(params).replace(/%([0-9A-F]{2})/g,
function toSolidBytes(match, option) {
return String.fromCharCode('0x' + option);
}));
},
//解密
decode(params) {
return decodeURIComponent(atob(params.replace(/\s/g, '+')).split('').map(option => '%' + ('00' + option.charCodeAt(0).toString(16)).slice(-2)).join(''));
}
}
\s : 表示 space ,空格
+: 一个或多个
^: 开始,^\s,以空格开始 结束,\s$,以空格结束
|:或者
/g:global, 全局