写点什么

一些前端开发小技巧,超级好用!

作者:秃头小帅oi
  • 2024-04-29
    福建
  • 本文字数:6193 字

    阅读完需:约 20 分钟

一些前端开发小技巧,超级好用!

​在实际的开发工作过程中,积累了一些常见又超级好用的 Javascript 技巧和代码片段,包括整理的其他大神的 JS 使用技巧,以供大家参考。本人的分享也是自己边学边做的笔记,若笔记内有错误内容或更优雅适合的写法方案,欢迎私信或评论留言互相学习~

在开始前,推荐一款程序员都应该知道的好物——JNPF 低代码开发

应用地址:https://www.jnpfsoft.com

这是一个基于 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;}
复制代码


用户头像

摸个鱼,顺便发点有用的东西 2023-06-19 加入

互联网某厂人(重生版)

评论

发布
暂无评论
一些前端开发小技巧,超级好用!_秃头小帅oi_InfoQ写作社区