前言
总结一下个人开发总封装的实用方法,以便后期开发方便
方法
合并表格行
在开发表格过程中,总是需要合并单元格子,后端会把相同的数据放在一起,前端处理合并,以下是利用哈希值处理的合并方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| function dealWithMergeData(tableData, matchKey) { let spanObject = {} matchKey.forEach((spanKeyItem) => { if (!spanObject[spanKeyItem]) spanObject[spanKeyItem] = []; let startIndex = 0; for (let i = 0; i < tableData.length; i++) { let tableItem = tableData[i]; if (i != 0) { if (tableItem[spanKeyItem] === tableData[i - 1][spanKeyItem]) { spanObject[spanKeyItem][startIndex].rowspan++; spanObject[spanKeyItem][i] = { rowspan: 0, colspan: 0 } } else { startIndex = i; spanObject[spanKeyItem][startIndex] = { rowspan: 1, colspan: 1 } } } else { spanObject[spanKeyItem][i] = { rowspan: 1, colspan: 1 } } } }) return spanObject }
|
reduce 进行数据结构的转换
1 2 3 4 5 6 7 8 9 10 11 12
| const arr = [ { id: "1", name: "张三", age: 11 }, { id: "1", name: "李四", age: 12 }, { id: "2", name: "王五", age: 13 }, { id: "3", name: "赵六", age: 14 }, { id: "2", name: "孔七", age: 15 } ];
function groupArrayByKey(arr = [], key) { return arr.reduce((t, v) => (!t[v[key]] && (t[v[key]] = []), t[v[key]].push(v), t), {}) } groupArrayByKey(arr, "id");
|
动态加载 JS 文件
在一些特殊的场景下,特别是一些库和框架的开发中,我们有时会去动态的加载 JS 文件并执行,下面是利用 Promise 进行了简单的封装。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function loadJS(files, done) { const head = document.getElementsByTagName('head')[0]; Promise.all(files.map(file => { return new Promise(resolve => { const s = document.createElement('script'); s.type = "text/javascript"; s.async = true; s.src = file; s.addEventListener('load', (e) => resolve(), false); head.appendChild(s); }); })).then(done); }
loadJS(["test1.js", "test2.js"], () => { });
|
利用闭包实现函数只执行一次
1 2 3 4 5 6 7 8 9 10
| export function once (fn) { let called = false return function () { if (!called) { called = true fn.apply(this, arguments) } } }
|
实现curring
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function add(a, b, c) { return a + b + c; } function currying(fn, ...args) { function curried(...args) { if (args.length >= fn.length) { return fn.apply(this, args) } else { return function (...arg2) { return curried.apply(this, args.concat(arg2)); } } } return curried.apply(this, args) } const a1 = currying(add, 1,2,3); const a2 = currying(add)(1)(2)(3);、、6
|
递归获取对象属性
如果让我挑选一个用的最广泛的设计模式,我会选观察者模式,如果让我挑一个我所遇到的最多的算法思维,那肯定是递归,递归通过将原始问题分割为结构相同的子问题,然后依次解决这些子问题,组合子问题的结果最终获得原问题的答案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| const user = { info: { name: "张三", address: { home: "Shaanxi", company: "Xian" }, }, };
function get(obj, path, fallback) { const parts = path.split("."); const key = parts.shift(); if (typeof obj[key] !== "undefined") { return parts.length > 0 ? get(obj[key], parts.join("."), fallback) : obj[key]; } return fallback; }
console.log(get(user, "info.name")); console.log(get(user, "info.address.home")); console.log(get(user, "info.address.company")); console.log(get(user, "info.address.abc", "fallback"));
|
大屏前端自适应
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
export const getScale = (w: number, h: number) => { const ww = window.innerWidth / w; const wh = window.innerHeight / h; return ww < wh ? ww : wh; };
export const screeResize = (el: HTMLDivElement, W: number, H: number) => { if (el) { el.style.width = `${W}px`; el.style.height = `${H}px`; el.style.transform = `scale(${getScale(W, H)}) translate(-50% ,-50%)`; } };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import { debounce } from "lodash"; import { screeResize } from "@/utils";
const dataScreenRef = ref<HTMLDivElement | null>(null); const onResize = () => { screeResize(dataScreenRef.value as HTMLDivElement, 1920, 1080); };
onMounted(()=>{ if (dataScreenRef.value) { onResize(); window.addEventListener("resize", debounce(onResize, 150)); }
|
1 2 3 4 5 6 7 8 9 10
| //大屏容器样式 .screenContainer{ transform-origin: left top; position: fixed; width: 1920px; height: 1080px; top: 50%; left: 50%; user-select: none; }
|
js获取url中指定参数的值(兼容hash)
1 2 3 4 5 6
| export const getQueryString = (name, search) => { search = search || window.location.search.substr(1) || window.location.hash.split("?")[1]; let reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)"); let r = search?.match(reg); if (r != null) return unescape(r[2]); return null; }
|
elementUI 封装自定义视频上传
1 2 3 4 5 6
| <el-upload action="#" ref="upload" :auto-upload="false" :file-list="fileList" list-type="picture-card" :limit="2" :on-change="onFileChange" :on-remove="onFileRemove" :on-exceed="handleExceed"> <el-icon> <Plus /> </el-icon> </el-upload>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| const fileList = ref([]);
const onFileChange = (uploadFile, uploadFiles) => { let uploadStatus = uploadVerify(uploadFile); if (uploadStatus == false) { uploadFiles.splice(uploadFiles.length - 1, 1); } fileList.value = uploadFiles; }
const onFileRemove = (uploadFile, uploadFiles) => { fileList.value = uploadFiles; }
const handleExceed = () => { ElMessage.warning(`最多上传2个图片`); }
const onFileRequest = async () => { let noUploadList = fileList.value.filter((v) => !v.fileId); let errorImgIndex = []; if (noUploadList.length) { let promiseArr = []; noUploadList.forEach((v, index) => { promiseArr.push(uploadHandle(index, v.raw, v.name, "景点图片")); }); let results = await Promise.all(promiseArr); dialogLoading.value = false results.forEach((v) => { if (v.code == "1001") { noUploadList[v.index].status = "success"; noUploadList[v.index].fileId = v.data; } else { errorImgIndex.push(v.index); } }); } if (errorImgIndex.length) { return ElMessage.warning( `第${errorImgIndex.join(",")}图片上传错误,请更改` ); }
}
const uploadHandle = (index, file, fileName, description = "") => { return new Promise(async resolve => { let splitName = fileName.split(","); if (splitName.length > 1) { var fileType = fileName .substring(fileName.lastIndexOf(".") + 1) .toLowerCase(); fileName = `${splitName[0] || 'random'}.${fileType}` } let uploadData = new FormData(); uploadData.append("file", file); uploadData.append("fileName", fileName); uploadData.append("description", description); let [res] = await awaitWrap(uploadPic(uploadData)) res.index = index; resolve(res); }) }
const uploadVerify = (file) => { let uploadStatus = true; let fileType = file.name .substring(file.name.lastIndexOf(".") + 1) .toLowerCase(); let restrictFileTypes = ["jpg", "png", "jpeg"]; const isLt2M = file.size / 1024 / 1024 < 10; if (!restrictFileTypes.includes(fileType)) { ElMessage.error("上传图片只能是 jpg、png、jpeg 格式!"); uploadStatus = false; } else if (!isLt2M) { ElMessage.error("上传图片大小不能超过 10MB!"); uploadStatus = false; } return uploadStatus; }
|