前端日常工作开发技巧汇总
一、JS篇
1. structuredClone 深拷贝
JavaScript 内置了一个 structuredClone() 的方法, 此方法提供了一种简单有效的方法来深度克隆对象,支持复杂数据类型,包括 Date、RegExp、Map、Set、ArrayBuffer、Blob、File 等。浏览器底层实现,通常比手动递归或 JSON 方法更高效。
兼容性
2. 函数式编程
ES14 更新了许多数组方法或者为原有的数组方法增加不会带来突变(without mutation) 的互补方法。意味着它们会基于原数组创建新的数组,而不是直接修改原数组。
新增的互补方法有
Array.sort() -> Array.toSorted()Array.splice() -> Array.toSpliced()Array.reverse() -> Array.toReversed()
新增的新数组方法有:Array.with()、Array.findLast()、Array.findLastIndex()
-
Array.with()
返回一个新数组,将原数组中指定索引index的元素替换为value,不修改原数组
语法 index:要替换的元素的索引(可以是负数,表示从末尾开始计数)。value:替换后的新值
const newArray = array.with(index, value)
const arr = [1, 2, 3, 4];
const newArr = arr.with(1, "hello"); // 替换索引 1 的元素
console.log(arr); // [1, 2, 3, 4](原数组不变)
console.log(newArr); // [1, "hello", 3, 4](新数组)
// 支持负数索引(从末尾开始)
const newArr2 = arr.with(-2, "world"); // 替换倒数第 2 个元素
console.log(newArr2); // [1, 2, "world", 4]
-
Array.findLast()
从数组末尾向前查找第一个满足callback条件的元素,并返回该元素。如果未找到,返回undefined -
Array.findLastIndex()
从数组末尾向前查找第一个满足callback条件的元素,并返回其索引。如果未找到,返回-1
3. 惰性函数
JavaScript 中的 惰性函数(Lazy Function) 是一种优化技术,其核心思想是:函数在第一次调用时执行一些初始化或判断逻辑,并在执行后将自身重定义为一个更高效或更简单的版本,后续调用就直接使用这个新版本,避免重复开销。
普通写法
function copyToClipboard(text) {
// 优先使用Clipboard API
if (navigator.clipboard) {
return navigator.clipboard
.writeText(text)
.then(() => {
Message.success('复制成功')
return true
})
.catch((err) => {
console.error('使用Clipboard API复制失败: ', err)
// 如果Clipboard API失败,尝试使用降级方案
return copyUsingExecCommand(text)
})
} else {
// 如果不支持Clipboard API,直接使用降级方案
return copyUsingExecCommand(text)
}
}
惰性写法
function copyToClipboard(text) {
// 第一次调用时进行能力检测,并重定义自身
if (navigator.clipboard) {
// 支持 Clipboard API
copyToClipboard = function (text) {
return navigator.clipboard
.writeText(text)
.then(() => {
console.log('文本已成功复制到剪贴板');
return true;
})
.catch((err) => {
console.error('Clipboard API 复制失败:', err);
return false;
});
};
} else {
// 不支持 Clipboard API,使用 execCommand 降级方案
copyToClipboard = function (text) {
return copyUsingExecCommand(text);
};
}
// 执行第一次调用
return copyToClipboard(text);
}
二、CSS篇
1. 滚动吸附
<template>
<div>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
</div>
</template>
<script setup name="Snap"></script>
<style lang="scss" scoped>
.container {
width: 100%;
height: 300px;
display: flex;
overflow-x: scroll;
// 吸附效果 mandatory: 必须吸附 proximity: 靠近时吸附
scroll-snap-type: x mandatory;
.item {
flex-shrink: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
color: #fff;
background-color: #ccc;
// 吸附位置
scroll-snap-align: start;
scroll-snap-stop: always;
&:nth-child(1) {
background-color: #f56c6c;
}
&:nth-child(2) {
background-color: #67c23a;
}
&:nth-child(3) {
background-color: #409eff;
}
}
}
</style>
兼容性较高
2. 字体自适应容器大小
<template>
<div>
<div class="container">
<p>字体自适应容器大小</p>
</div>
</div>
</template>
<script setup name=""></script>
<style lang="scss" scoped>
.container {
width: 500px;
height: 300px;
padding: 15px;
resize: both;
overflow: hidden;
background-color: aquamarine;
container-type: inline-size; // 启用容器查询 size:基于宽高 / inline-size 基于宽度 / normal 不启用
p {
font-size: 5cqh;
}
}
</style>
兼容性还行
3. 选择器
- 选择器特定性(通常叫做选择器权重)
当希望某个css属性优先级高于其他属性值时,尽量不要使用!important,!important会打破这些固有的级联规则,使得样式的应用变得不那么可预测。这可能会导致样式表难以维护和理解,尤其是在大型项目中。增加调试难度,也限制了样式的灵活性。
替代方案: 通过编写更具体(或更精确)的选择器来覆盖样式,或者叠加选择器,比如:222
.el-button.el-button {
color: red;
}
- 新型选择器
:has()选择器: 根据一个元素是否包含某些特定的后代元素,或者其后的同级元素是否满足某些条件,来选中该元素本身。这实现了“向下”观察的能力。
示例1: 选择包含 <img> 的 <div>
<div>这个 div 没有图片,不会被选中</div>
<div>
<img src="example.jpg" alt="示例图片">
这个 div 包含图片,会被红色边框包围
</div>
/* 选择包含 <img> 的 div */
div:has(img) {
border: 3px solid red; padding: 10px;
}
示例2: 选择紧跟着 <p> 的 <h2>
<h2>这个 h2 后面没有紧跟着 p,不会被选中</h2>
<div>分隔内容</div>
<h2>这个 h2 后面紧跟着 p</h2>
<p>这个 p 是 h2 的紧邻兄弟元素,因此 h2 会变成蓝色斜体</p>
/* 选择后面紧跟着 <p> 的 h2 */
h2:has(+ p) {
color: blue; font-style: italic;
}
兼容性
:is()选择器: 它接受一个逗号分隔的选择器列表作为参数,并匹配其中任意一个选择器。这有助于减少冗余代码,提高可读性。:is() 的权重等于它括号里所有选择器中权重最高的那个。
示例:
<header>
<h1>这是 header 的 h1(紫色)</h1>
</header>
<main>
<h1>这是 main 的 h1(紫色)</h1>
</main>
<footer>
<h1>这是 footer 的 h1(紫色)</h1>
</footer>
<section>
<h1>这个 h1 不在 :is() 范围内,保持默认颜色</h1>
</section>
/* 统一设置 header、main、footer 下的 h1 样式 */
:is(header, main, footer) h1 {
color: purple; font-family: Arial, sans-serif;
}
兼容性
:where()选择器: 与 :is() 类似,但权重永远为 0,适合默认样式。
兼容性
三、VUE篇
1. v-memo
Vue 3 提供的性能优化指令,其作用是通过缓存模板子树的渲染结果,仅在依赖项变化时重新渲染,从而减少不必要的虚拟 DOM 计算和更新操作。
v-memo 接收一个依赖数组,只有当数组中的值发生变化时才会重新渲染。
示例:优化大型列表渲染,避免全量更新。
当 item.id 或 item.status 变化时,仅更新对应项;其他项复用缓存结果
<div v-for="item in list" :key="item.id" v-memo="[item.id, item.status]">
{{ item.content }}
<StatusBadge :status="item.status" />
</div>
2. watch —— 副作用和深度监听
3. customRef ——— 自定义响应式依赖追踪
4. 组件的二次封装
四、Chrome浏览器调试技巧
1. $0
2. 模拟聚焦网页
3. 重放XHR
五、VSCode编辑器插件分享
1. i18n Ally
- 代码内直接预览翻译文本
- 快速生成初始翻译
- 一键跳转至对应翻译条目
- 集中管理
"i18n-ally.localesPaths": ["./src/i18n/lang/locales"], // 翻译文件夹路径
"i18n-ally.pathMatcher": "{locale}/**/{namespace}.json", // 翻译目标文件路径匹配
"i18n-ally.keystyle": "nested", // 翻译路径格式,
"i18n-ally.sourceLanguage": "zh-CN", // 翻译源语言
"i18n-ally.displayLanguage": "zh-CN", //显示语言, 这里也可以设置显示英文为en
"i18n-ally.sortKeys": true, // 是否自动排序
"i18n-ally.namespace": false, // 是否启用命名空间,一般在积攒多个待翻译文案时启用,可以自动编辑至对应文件中
"i18n-ally.enabledParsers": ["ts", "js", "json"], // 翻译文件可允许的格式,默认json
2. koroFileHeader @4.9.2
用于生成文件头部注释和函数注释的插件
快捷键:
- 头部注释:
Ctrl+Win+I(Windows/Linux)或Ctrl+Cmd+I(Mac) - 函数注释:
Ctrl+Win+T(Windows/Linux)或Ctrl+Cmd+T(Mac)
// 头部注释
"fileheader.customMade": {
"Author": "git config user.name && git config user.email", // 同时获取用户名与邮箱
"Date": "Do not edit", // 文件创建时间
"LastEditors": "git config user.name && git config user.email", // 文件最后编辑者 与Author字段一致
"LastEditTime": "Do not edit", // 文件最后编辑时间
"FilePath": "Do not edit", // 文件在项目中的相对路径 自动更新
"Description": "" // 文件描述
},