一些前端开发小技巧,超级好用!
作者:秃头小帅oi
- 2024-04-29 福建
本文字数:6193 字
阅读完需:约 20 分钟

在实际的开发工作过程中,积累了一些常见又超级好用的 Javascript 技巧和代码片段,包括整理的其他大神的 JS 使用技巧,以供大家参考。本人的分享也是自己边学边做的笔记,若笔记内有错误内容或更优雅适合的写法方案,欢迎私信或评论留言互相学习~
在开始前,推荐一款程序员都应该知道的好物——JNPF 低代码开发
这是一个基于 Java Boot/.Net Core 构建的简单、跨平台快速开发框架,包含表单建模、流程设计、报表可视化、代码生成器、系统管理、前端 UI 等组件,这种情况下我们避免了重复造轮子,已内置大量的成熟组件,选择合适的组件进行集成或二次开发复杂功能,即可自主开发一个属于自己的应用系统。
另外,后续会持续分享前端开发的其他相关的知识总结等,那么,我们开始吧~
日期格式化
// 格式化日期类型,fmt格式可选择function dateFormat(fmt, date) { let ret; let opt = { "Y+": date.getFullYear().toString(), // 年 "M+": (date.getMonth() + 1).toString(), // 月 "D+": date.getDate().toString(), // 日 "h+": date.getHours().toString(), // 时 "m+": date.getMinutes().toString(), // 分 "s+": date.getSeconds().toString(), // 秒 "ms+": date.getMilliseconds().toString() // 毫秒 }; for (let k in opt) { ret = new RegExp("(" + k + ")").exec(fmt); if (ret) { fmt = fmt.replace(ret[1], ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, "0")); } } return fmt;}// 格式化当前时间dateFormat("YYYY-MM-DD hh:mm:ss.ms", new Date());// 格式化特定时间let date = new Date();let fDate = dateFormat("YYYY-MM-DD hh:mm:ss.ms", new Date(date));复制代码
时间转换(秒数转时分秒)
function timeFormat (sec) { let minite = Math.floor((sec / 60 % 60)) < 10 ? '0' + Math.floor((sec / 60 % 60)) : Math.floor((sec / 60 % 60)); let second = Math.floor((sec % 60)) < 10 ? '0' + Math.floor((sec % 60)) : Math.floor((sec % 60)); if (sec < 3600) { return `${minite}:${second}`; } else { let hour = Math.floor(sec / 3600) < 10 ? '0' + Math.floor(sec / 3600) : Math.floor(sec / 3600); return `${hour}:${minite}:${second}`; }}复制代码
计算时分秒差值
// 计算时分秒差值function timeDiffer(beginTime, endTime) { let ret = {}; let date = new Date(); let sTime = Date.parse(dateFormat("YYYY/MM/DD", date) + " " + beginTime); if (beginTime >= endTime) { date.setDate(date.getDate() + 1); } let eTime = Date.parse(dateFormat("YYYY/MM/DD", date) + " " + endTime); let differ = eTime - sTime; let hour = Math.floor(differ / 1000 / 60 / 60); let minute = Math.floor(differ / 1000 / 60 - hour * 60); let second = Math.floor(differ / 1000 - hour * 60 * 60); ret = { differHour: hour, differMinute: minute, differSecond: second }; return ret;}let { differHour, differMinute, differSecond } = timeDiffer(beginTime, endTime);复制代码
(数组/对象)(深/浅)拷贝
let list = [{ name: "o" }];let obj = { stu: { name: "o" } };
// 数组浅拷贝let listCopy1 = [].concat(list);let listCopy2 = list.slice();let listCopy3 = Array.from(list);let listCopy4 = [...list];
// 对象浅拷贝let objCopy1 = Object.assign({}, obj);let objCopy2 = { ...obj };
// 数组|对象深拷贝let listCopy = JSON.parse(JSON.stringify(list));let objCopy = JSON.parse(JSON.stringify(obj));
// 深拷贝,即复制并独立一份数据,操作不影响原数据function deepCopy(obj) { if (typeof obj !== "object") { return obj; } let result = Array.isArray(obj) ? [] : {}; for (let i in obj) { if (obj.hasOwnProperty(i)) { if (typeof obj[i] === "object" && obj[i] !== null) { result[i] = deepCopy(obj[i]); } else { result[i] = obj[i]; } } } return result;}
// 深拷贝function deepClone(obj) { let copyObj = null; if (typeof obj === "object" && obj !== null) { copyObj = Array.isArray(obj) ? [] : {}; for (let i in obj) { copyObj[i] = deepClone(obj[i]); } } else { copyObj = obj; } return copyObj;}复制代码
数组去重
// ES6最简方法let result = [];if (Array.isArray(arr)) { result = new Set(arr);}function unique(arr) { return Array.from(new Set(arr));}
// filter去重function unique(arr) { return arr.filter((item, index, arr) => { // 当前元素在原数据中的第一个索引等于当前索引值,否则返回当前元素 return arr.indexOf(item, 0) == index; });}
// 数组去重function unique(arr) { if (!Array.isArray(arr)) { return; } let result = []; for (let i = 0; i < arr.length; i++) { if (result.indexOf(arr[i]) === -1) { result.push(arr[i]); } } return result;}function unique(arr) { if (Array.isArray(arr)) { let result = []; for (let i = 0, len = arr.length; i < len; i++) { if (!result.includes(arr[i])) { result.push(arr[i]); } } return result; }}复制代码
数组对象排序
// 数组对象排序,比较两个字符串list.sort((a, b) => { return a.id.localeCompare(b.id);});复制代码
获取上/下个月日期
// 下个月let date = new Date(this.startDate);let nextMonthDate = date.setMonth(date.getMonth() + 1);this.endDate = dateFormat("YYYY-MM-DD", new Date(nextMonthDate));
// 上个月let lastMonthDate = date.setMonth(date.getMonth() - 1);复制代码
获取前/后 7 天日期
// 前7天let date = new Date(this.startDate);let afterDate = date.setDate(date.getDate() + 6);this.endDate = dateFormat("YYYY-MM-DD", new Date(afterDate));
// 后7天let afterDate = date.setDate(date.getDate() - 6);复制代码
一周日期
let weeks=["周一","周二","周三","周四","周五","周六","周日"];for (let i = 0; i<7; i++){ let date = new Date(); let index = date.getDay() ? date.getDay() - 1 : 6; let nowDate = date.setDate(date.getDate() - index + i); let formatDate = dateFormat("MM-DD", new Date(nowDate)); let week = weeks[i]; let weekDate = `${formatDate}(${week})`; this.weekDateColumns.push(weekDate);}复制代码
点击内容切换
let len = this.assistList.length - 1;if (this.index < len) { this.index++; this.assistInfo = this.assistList[this.index];} else { this.index = 0; this.assistInfo = this.assistList[this.index];}复制代码
时分秒
时:`parseInt(count/60/60)`分:`parseInt(count/60)%60`秒:`parseInt(count%60)`复制代码
数组对象,拼接字符串
let arr = [ { id: 1, name: "Andy" }, { id: 2, name: "Jim" }, { id: 3, name: "Lucy" }, { id: 4, name: "Cherry" },];let str = arr.map((item) => { return item.name;}).join(",");复制代码
当月第一天和最后一天
// 第一天let date = new Date();date.setDate(1);console.log(dateFormat("YYYY-MM-DD", date));
// 最后一天let date = new Date();let lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0);console.log(dateFormat("YYYY-MM-DD", lastDay));复制代码
fetch接口请求
let api = "https://api.com";let headerConfig = { headers: { Accept: "application/json", },};async function request() { let res = await fetch(api, headerConfig); let data = await res.json();}复制代码
按键处理方法
window.addEventListener("keydown", (e) => { let container = document.querySelector("#container"); let { key, keyCode, code } = e; let template = ""; [ { title: "e.key", content: key == " " ? "Space" : key, }, { title: "e.keyCode", content: keyCode, }, { title: "e.code", content: code, }, ].forEach((item) => { template += `<div class="key"><small>${item.title}</small>${item.content}</div>`; }); container.innerHTML = template;});复制代码
返回顶部
html,body { scroll-behavior: smooth;}.back { position: sticky; float: right; top: -110px; margin-top: -50px; border-radius: 50%; background: url("") center no-repeat dodgerblue; background-size: 50%; width: 50px; height: 50px; transform: translateY(calc(100vh + 50px));}复制代码
自适应内部元素
figure { max-width: 300px; max-width: min-content; margin: auto;}figure > img { max-width: inherit;}复制代码
iview 封装菜单 menu
<template> <i-submenu :name="menuList.name"> <!-- 父级菜单 --> <template slot="title">{{ menuList.title }}</template> <template v-for="(item, index) in menuList.children"> <!-- 如果还要子集,继续调用 --> <left-menu-nav v-if="item.hasOwnProperty('children')" :menuList="item"></left-menu-nav> <!-- 无子菜单 --> <i-menu-item v-else :name="item.name">{{ item.title }}</i-menu-item> </template> </i-submenu></template>
<script>export default { name: "leftMenuNav", props: { menuList: { type: Object, default: () => { } } }};</script>
<Layout> <Sider hide-trigger collapsible :width="192" :collapsed-width="64" v-model="collapsed" class="left-sider" :style="{ overflow: 'hidden' }"> <i-menu class="menu-position" ref="menu" :active-name="selectItem" :open-names="menuOpenName" @on-select="changeSelectItem"> <template v-for="(item, index) in menuList" :name="item.name"> <!-- 有子菜单 --> <left-menu-nav v-if="item.hasOwnProperty('children')" :menuList="item"></left-menu-nav> <!-- 无子菜单 --> <i-menu-item v-else :name="item.name">{{ item.title }}</i-menu-item> </template> </i-menu> </Sider> <Content class="main-content-con"> <Layout class="main-layout-con"> <Content class="content-wrapper" style="position: relative"> <router-view style="height: 100%" /> <div v-show="lockEnable" class="lockBox"></div> <ABackTop :height="100" :bottom="80" :right="50" container=".content-wrapper"></ABackTop> </Content> </Layout> </Content></Layout>复制代码
图片懒加载
const images = document.querySelectorAll("img");const callback = (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { const image = entry.target; const data_src = image.getAttribute("data-src"); image.setAttribute("src", data_src); ResizeObserver.unobserver(image); } });};const observer = new IntersectionObserver(callback);images.forEach((image) => { observer.observe(image);});复制代码
CSS 多行文本省略
p { overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4;}复制代码
Vue 字符串换行
1. 添加`white-space:pre`2. 使用`<pre>`标签替换复制代码
封装 iView 无限层级菜单
// 子组件<template> <i-submenu :name="menuList.name"> <!-- 父级菜单 --> <template slot="title">{{menuList.title}}</template> <template v-for="(item,index) in menuList.children"> <!-- 如果还要子集,继续调用 --> <left-menu-nav v-if="item.children&&item.children.length" :menuList="item" :key="item.index"></left-menu-nav> <!-- 子菜单 --> <i-menu-item :key="item.id" :name="item.name">{{item.title}}</i-menu-item> </template> </i-submenu></template>
<script>export default { name: "leftMenuNav", props: { menuList: { type: Object, default: () => { } } }}</script>复制代码
// 父组件<i-menu :active-name="selectItem" :open-names="menuOpenName" @on-select="changeSelectItem"><template v-for="(item, index) in menuList" :name="item.name"> <!-- 有子菜单 --> <left-menu-nav v-if="item.children && item.children.length" :menuList="item" :key="item.name"></left-menu-nav> <!-- 无子菜单 --> <i-menu-item v-else :name="item.name" :key="item.name">{{ item.title }}</i-menu-item></template></i-menu>复制代码
上传文件
<div class="upload"> <button id="btn" class="btn">上传文件</button> <input type="file" id="input" class="input" /></div>复制代码
.upload { width: 100px; height: 100px; position: relative;}.btn { width: 100%; height: 100%; box-sizing: border-box; border: 1px dashed rgb(31, 154, 158); background: #fff; cursor: pointer;}.input { width: 100%; height: 100%; box-sizing: border-box; position: absolute; left: 0; top: 0; opacity: 0;}复制代码
CSS控制禁止点击
pointer-events: none; //(禁止鼠标点击事件)
单行居中,多行顶部对齐
.table-item { height: 100%; box-sizing: border-box; display: flex; flex: 1; flex-wrap: wrap; align-items: center; justify-content: center; font-size: 16upx; text-align: justify; font-weight: 600; span { width: 125upx; height: 65upx; overflow: auto; display: flex; align-items: center; justify-content: center; display: -webkit-box; -webkit-box-orient: vertical; } }复制代码
计算传入时间与当前时间相差的秒数
function convertStrToTime (time) { let nowTime = new Date().getTime(); let date = new Date(); let arr = time.split(":"); date.setHours(parseInt(arr[0])); date.setMinutes(parseInt(arr[1])); let endTime = new Date(date).getTime(); let ret = Math.ceil((endTime - nowTime) / 1000); return ret;}复制代码
划线
评论
复制
发布于: 刚刚阅读数: 4
秃头小帅oi
关注
摸个鱼,顺便发点有用的东西 2023-06-19 加入
互联网某厂人(重生版)







评论