主要记录一些在项目中经常用到模块,进行了一个封装,增加代码的可维护性及易读性。
1.比较两个对象/数组..中的值是否完全相等
// 对比两个对象之间的差别
contrastObjSame(originObj, curObj) {
if(originObj === undefined || curObj === undefined) {
return false;
}
if(Object.prototype.toString.call(originObj) !== Object.prototype.toString.call(curObj)) {
return false;
}
if(typeof originObj !== 'object') {
if(originObj !== curObj) {
return false;
}
return true;
} else if(Object.prototype.toString.call(originObj).toLowerCase().indexOf(' object') >= 0) {
let originObjKeyArr = Object.keys(originObj);
let curObjKeyArr = Object.keys(curObj);
if(originObjKeyArr.length !== curObjKeyArr.length) {
return false;
}
for(let key in originObj) {
if(curObj[key] === undefined) {
return false;
}
if(!this.contrastObjSame(originObj[key], curObj[key])) {
return false;
}
}
return true;
} else if(Object.prototype.toString.call(originObj).toLowerCase().indexOf(' array') >= 0) {
let originLen = originObj.length;
let curLen = originObj.length;
if(originLen !== curLen) {
return false;
}
for(let i = 0; i < originLen; i++) {
if(!this.contrastObjSame(originObj[i], curObj[i])) {
return false;
}
}
return true;
} else{
return originObj === curObj;
}
}
2.深拷贝
deepCopy(o) {
// 数组
if (o instanceof Array) {
return o.map(item => {
return this.deepCopy(item);
});
} else if (o instanceof Object) {
let temp = {};
Object.keys(o).map(item => {
temp[item] = this.deepCopy(o[item]);
});
return temp;
} else {
return o;
}
}
3.值校验
/** 值校验
* @params:
* {obj.name}校验的值;
* {obj.errorTip}错误显示内容;
* {obj.required}是否必填;
* {obj.regExp}正则数组;
* {obj.regExp[index].reg}校验规则-正则
* {obj.regExp[index].attr}校验规则属性-正则
* {obj.regExp[index].ifForbid}校验规则-true:符合规则的不通过;false:符合规则的通过
* {obj.regExp[index].err}错误提示
*/
validateValue(value, obj, item) {
if (typeof obj === 'undefined') {
return {
result: true,
msg: '不存在校验项'
};
} else if (typeof value === 'undefined' && typeof obj.errorTip !== 'undefined') {
obj.errorTip = '';
return {
result: true,
msg: '不存在校验项'
};
} else if (typeof value === 'undefined' && typeof obj.errorTip === 'undefined') {
return {
result: true,
msg: '不存在校验项&不存在信息错误提示'
};
}
if (typeof obj.errorTip !== 'undefined') {
obj.errorTip = '';
}
if (obj.required && (!value && value !== 0)) {
if (typeof obj.errorTip !== 'undefined') {
obj.errorTip = '请输入正确的值';
}
return {
result: false,
ifRequiredFill: false,
msg: '请输入正确的值'
};
} else if (obj.regExp && obj.regExp.length > 0) {
for (var i = 0, len = obj.regExp.length; i < len; i++) {
let attr = obj.regExp[i].attr || 'ig';
let pattern = new RegExp(obj.regExp[i].reg, attr);
let ifForbid = obj.regExp[i].ifForbid || false;
let ifHasValueCheck = obj.regExp[i].ifHasValueCheck || false;
if (ifHasValueCheck && !value) {
continue;
}
if (value && ((ifForbid && pattern.test(value)) || (!ifForbid && !pattern.test(value)))) {
if (obj.regExp[i].err && typeof obj.errorTip !== 'undefined') {
obj.errorTip = obj.regExp[i].err;
}
break;
}
}
if (i >= len) {
return {
result: true,
msg: '校验通过'
};
} else {
return {
result: false,
ifRequiredFill: true,
msg: obj.regExp[i].err || '校验未通过'
};
}
} else {
return {
result: true,
msg: '校验通过'
};
}
}
4.生成随机数
// 生成随机数
getRandomNum(randomLength) {
let rL = randomLength || 18;
return Number(Math.random().toString().substr(3, rL) + Date.now()).toString(36);
}
5.文件导出
// 导出文件 - base64转为文件
base64ToFile(base64Data, tempfilename, contentType) {
if (!base64Data) {
return;
}
contentType = contentType || 'application/vnd.ms-excel';
var sliceSize = 1024;
var byteCharacters = atob(base64Data);
var bytesLength = byteCharacters.length;
var slicesCount = Math.ceil(bytesLength / sliceSize);
var byteArrays = new Array(slicesCount);
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
var begin = sliceIndex * sliceSize;
var end = Math.min(begin + sliceSize, bytesLength);
var bytes = new Array(end - begin);
for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
bytes[i] = byteCharacters[offset].charCodeAt(0);
}
byteArrays[sliceIndex] = new Uint8Array(bytes);
}
var file = new File(byteArrays, tempfilename, { type: contentType });
return file;
},
// 导出文件 -- 下载二进制流binary
// 注意download兼容性不佳
downloadBinary(data, filename, type) {
if (!data) {
return;
}
type = type || 'application/vnd.ms-excel';
var file = new Blob([data], { type: type });
if (window.navigator.msSaveOrOpenBlob) // IE10+
window.navigator.msSaveOrOpenBlob(file, filename);
else { // Others
var link = document.createElement("a"),
url = URL.createObjectURL(file);
link.style.display = 'none';
link.href = url;
link.download = filename || this.getRandomNum();
document.body.appendChild(link);
link.click();
setTimeout(function() {
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
}, 0);
}
},
// 导出文件 -- base64 -- 先转为binary-文件-blob在下载
downloadBase64File(data, filename, type) {
if (!data) {
return;
}
this.downloadBinary(this.base64ToFile(data, filename, type), filename, type);
},
// 导出文件 -- 下载base64
// 注意download兼容性不佳
// 注释部分有待检验
downloadBase64(data, filename, type) {
if (!data) {
return;
}
type = type || 'application/vnd.ms-excel';
let file = `data:${type};base64,${data}`
// if (window.navigator.msSaveOrOpenBlob) // IE10+
// window.navigator.msSaveOrOpenBlob(file, filename);
// else { // Others
var link = document.createElement("a"),
url = file;
link.style.display = 'none';
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
}
6.格式化时间
// 获取时间
// @params: {time}时间戳/date格式;{format}显示示格式 Y-M-D H:F:S
getFormateTime(time, formatStr) {
let format = formatStr || 'Y-M-D';
if (!time) return '- -';
// if (time.toString().length !== 13) return time;
if (!(Object.prototype.toString.call(time).toLowerCase().indexOf('date') >= 0 || typeof time === 'number' || typeof time === 'string')) {
return '- -';
}
let date = null;
if (Object.prototype.toString.call(time).toLowerCase().indexOf('date') < 0) {
time = parseInt(time);
date = new Date(time);
}
if (Object.prototype.toString.call(date).toLowerCase().indexOf('date') < 0) {
return '- -';
}
let year = date.getFullYear();
let month = date.getMonth() + 1;
month = month < 10 ? '0' + month : month;
let day = date.getDate();
day = day < 10 ? '0' + day : day;
let hours = date.getHours();
hours = hours < 10 ? '0' + hours : hours;
let minutes = date.getMinutes();
minutes = minutes < 10 ? '0' + minutes : minutes;
let seconds = date.getSeconds();
seconds = seconds < 10 ? '0' + seconds : seconds;
// 去头尾空格
format = format.replace(/(^\s*)|(\s*$)/g, '');
format = format.replace(/(Y|y)/gi, year);
format = format.replace(/(M|m)/gi, month);
format = format.replace(/(D|d)/gi, day);
format = format.replace(/(H|h)/gi, hours);
format = format.replace(/(F|f)/gi, minutes);
format = format.replace(/(S|s)/gi, seconds);
return format;
}
// 获取距离现在XX天的时间
// 有大的值取大的(1年10月 = 1年前)
// @params: {time}时间戳/date格式;{format}显示示格式最小的显示时间:Y/M/D/H/F/S
getFromTime(time, format) {
if (!time) return "- -";
// if (time.toString().length != 13) return time;
if (!(Object.prototype.toString.call(time).toLowerCase().indexOf('date') >= 0 || typeof time === 'number' || typeof time === 'string')) {
return '- -';
}
let date = null;
if (Object.prototype.toString.call(time).toLowerCase().indexOf('date') < 0) {
time = parseInt(time);
date = new Date(time);
}
if (Object.prototype.toString.call(date).toLowerCase().indexOf('date') < 0) {
return '- -';
}
// 默认最小是天
let level = 3;
switch (format) {
case 'Y':
level = 1;
break;
case 'M':
level = 2;
break;
case 'D':
level = 3;
break;
case 'H':
level = 4;
break;
case 'F':
level = 5;
break;
case 'S':
level = 6;
break;
};
let curDate = new Date();
if (level <= 3) {
curDate.setHours(date.getHours());
}
if (level <= 4) {
curDate.setMinutes(date.getMinutes());
}
if (level <= 5) {
curDate.setSeconds(date.getSeconds());
}
curDate.setMilliseconds(date.getMilliseconds());
let tag = curDate - date < 0 ? "后" : "前";
let timeOffset = Math.abs(curDate.getTime() - date.getTime()) / 1000;
let secondsOffset = Math.floor(timeOffset);
let minutesOffset = Math.floor(timeOffset / 60);
let hoursOffset = Math.floor(timeOffset / 60 / 60);
let dayOffset = Math.floor(timeOffset / 60 / 60 / 24);
if (level <= 3) {
dayOffset = curDate - date > 0 ? Math.floor(timeOffset / 60 / 60 / 24) : Math.ceil(timeOffset / 60 / 60 / 24);
}
let monthOffset = Math.floor(dayOffset / 30);
let yearOffset = Math.floor(dayOffset / 365);
let ans = '';
if (yearOffset !== 0 && level >= 1) {
ans = `${yearOffset} 年`;
} else if (monthOffset !== 0 && level >= 2) {
ans = `${monthOffset} 月`;
} else if (dayOffset !== 0 && level >= 3) {
ans = `${dayOffset} 天`;
} else if (hoursOffset !== 0 && level >= 4) {
ans = `${hoursOffset} 小时`
} else if (minutesOffset !== 0 && level >= 5) {
ans = `${minutesOffset} 分钟`
} else if (secondsOffset !== 0 && level >= 6) {
ans = `${secondsOffset} 秒`;
} else if (level === 3) {
ans = '今天';
} else if (level > 3) {
ans = '刚刚'
}
ans = (ans === '今天' || ans === '刚刚') ? ans : ans + tag;
return ans;
}
终极版
// 时间格式化辅助函数 date:毫秒数 format:'yyyy-MM-dd hh:mm:ss'
dateTimeFormatter(date, format) {
if (!date || date == "") {
return ""
}
if (typeof date === "string") {
var mts = date.match(/(\/Date\((\d+)\)\/)/)
if (mts && mts.length >= 3) {
date = parseInt(mts[2])
}
}
date = new Date(date)
if (!date || date.toUTCString() == "Invalid Date") {
return ""
}
var map = {
"M": date.getMonth() + 1, //月份
"d": date.getDate(), //日
"h": date.getHours(), //小时
"m": date.getMinutes(), //分
"s": date.getSeconds(), //秒
"q": Math.floor((date.getMonth() + 3) / 3), //季度
"S": date.getMilliseconds() //毫秒
}
format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
var v = map[t]
if (v !== undefined) {
if (all.length > 1) {
v = '0' + v
v = v.substr(v.length - 2)
}
return v
} else if (t === 'y') {
return (date.getFullYear() + '').substr(4 - all.length)
}
return all
})
return format
}
7. vue element-ui 指令 - 让弹窗可移动
// 让elemntui的el-dialog可以移动
// 调用方式v-dialogDrag='弹窗显示/隐藏参数'
dialogDrag: {
bind(el, binding, vnode, oldVnode) {
const dialogHeaderEl = el.querySelector('.el-dialog__header');
const dragDom = el.querySelector('.el-dialog');
const windowWidth = document.body.clientWidth;
const windwoHeight = document.body.clientHeight;
// 空间不足,禁止移动
if (windowWidth <= dragDom.offsetWidth && windwoHeight <= dragDom.offsetHeight) {
return;
}
// 初始化
el.style.overflow = 'visible';
el.style.marginTop = dragDom.style.marginTop;
el.style.marginLeft = 'auto';
el.style.marginRight = 'auto';
setTimeout(() => {
el.style.left = (windowWidth - dragDom.offsetWidth) / 2 + 'px';
}, 0);
el.style.right = 'auto';
el.style.bottom = 'auto';
dragDom.style.marginTop = 0;
dialogHeaderEl.style.cursor = 'move';
// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
const sty = el.currentStyle || window.getComputedStyle(el, null);
const styMarginTop = el.style.marginTop;
dialogHeaderEl.onmousedown = (e) => {
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - dialogHeaderEl.offsetLeft;
const disY = e.clientY - dialogHeaderEl.offsetTop;
// 获取到的值带px 正则匹配替换
let styL, styT;
// 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
if (sty.left.includes('%')) {
styL = +windowWidth * (+sty.left.replace(/\%/g, '') / 100);
styT = +windwoHeight * (+sty.top.replace(/\%/g, '') / 100);
} else {
styL = +sty.left.replace(/\px/g, '');
styT = +sty.top.replace(/\px/g, '');
};
document.onmousemove = function(e) {
// 通过事件委托,计算移动的距离
let l = e.clientX - disX + styL;
let t = e.clientY - disY + styT;
let marginTopPx = styMarginTop;
let leftOver = windowWidth - dragDom.offsetWidth;
if (styMarginTop.indexOf('vh') >= 0) {
marginTopPx = windwoHeight / 100 * parseFloat(styMarginTop.replace(/\px/g, ''))
}
let marginBottomLeft = windwoHeight - marginTopPx - el.offsetHeight + 50;
// 边界值控制
if (l < 0 && windowWidth > dragDom.offsetWidth) {
l = 0;
} else if (l > leftOver && windowWidth > dragDom.offsetWidth) {
l = leftOver;
}
if (t < -marginTopPx && windwoHeight > dragDom.offsetHeight) {
t = -marginTopPx;
} else if (t > marginBottomLeft && windwoHeight > dragDom.offsetHeight) {
t = marginBottomLeft;
}
// 移动当前元素
if (windowWidth > dragDom.offsetWidth) {
el.style.left = `${l}px`;
}
if (windwoHeight > dragDom.offsetHeight) {
el.style.top = `${t}px`;
}
//将此时的位置传出去
//binding.value({x:e.pageX,y:e.pageY})
};
document.onmouseup = function(e) {
document.onmousemove = null;
document.onmouseup = null;
};
}
},
update(el, binding, vnode, oldVnode) {
const dragDom = el.querySelector('.el-dialog');
const windowWidth = document.body.clientWidth;
// 恢复位置
if (binding.value && binding.oldValue !== binding.value) {
setTimeout(() => {
el.style.left = (document.body.clientWidth - dragDom.offsetWidth) / 2 + 'px';
el.style.top = 0;
}, 0);
}
}
}
以上内容,如有错误请指出,不甚感激。
如需转载,请注明出处