一些前端开发小技巧,超级好用!
作者:秃头小帅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 加入
互联网某厂人(重生版)
评论