主要記錄一些在項目中常常用到模塊,進行了一個封裝,增長代碼的可維護性及易讀性。vue
// 對比兩個對象之間的差異 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; } }
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; } }
/** 值校驗 * @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: '校驗經過' }; } }
// 生成隨機數 getRandomNum(randomLength) { let rL = randomLength || 18; return Number(Math.random().toString().substr(3, rL) + Date.now()).toString(36); }
// 導出文件 - 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(); }
// 獲取時間 // @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; }
終極版node
// 時間格式化輔助函數 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 }
// 讓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); } } }
以上內容,若有錯誤請指出,不甚感激。
如需轉載,請註明出處element-ui