🍉 前言
前端开发中,很多 Bug 并不是逻辑复杂导致的,而是基础知识点模糊、习惯性错误写法 引发。不管是日常业务开发、联调排错,还是面试笔试,这些坑都高频出现。本篇整理 HTML、CSS、JavaScript、Vue3 四大模块 易错点,每一点包含:错误示例、原因分析、正确写法、避坑总结,CSDN 直接复制即可发布,代码自带高亮、结构分层清晰,适合收藏 + 复盘。
适用人群:前端初级开发者、实习生、面试刷题、日常查错
一、HTML 易错知识点
1. 标签嵌套规则错误
错误写法
html
预览
<!-- 行内嵌套块级、p标签嵌套块级 都是不规范 -->
<span>
<div>文本</div>
</span>
<p>
<h3>标题</h3>
</p>
错误原因
- 行内元素:
span/a/input/button只能嵌套行内元素 / 文本; p、h1~h6属于特殊块级,禁止嵌套块级元素;- 浏览器会自动拆解标签,造成页面结构错乱、样式异常。
正确规范
- 布局容器统一用
div; - 文本行内修饰用
span; - 段落只放文本、行内标签。
2. 表单缺失 name 属性
错误现象
表单提交后端拿不到参数、单选框复选框无法分组。
html
预览
<!-- 错误:无name,提交无参数 -->
<input type="text" placeholder="账号">
<!-- 错误:radio不同名,无法互斥 -->
<input type="radio">男
<input type="radio">女
正确写法
html
预览
<input type="text" name="username" placeholder="账号">
<input type="radio" name="gender" value="1">男
<input type="radio" name="gender" value="2">女
✅ 核心:表单提交、数据采集完全依赖 name 属性。
3. 自闭合标签书写不规范
常见自闭合标签:img、input、link、meta、br、hr
html
预览
<!-- 错误 -->
<img src="xxx.jpg"></img>
<input type="text"></input>
<!-- 正确 -->
<img src="xxx.jpg" alt="描述">
<input type="text">
二、CSS 高频踩坑点
1. 盒模型 width 计算误区
默认 box-sizing: content-box元素实际宽度 = width + padding + border
css
.box {
width: 200px;
padding: 0 20px;
border: 1px solid #eee;
/* 实际宽度 > 200px,容易撑开布局 */
}
全局通用解决方案(项目必加)
css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
设置后:width 包含 padding + border,布局更可控。
2. 浮动塌陷问题
子元素设置 float,父元素高度塌陷为 0。
经典清除浮动方案
css
.clearfix::after {
content: "";
display: block;
clear: both;
visibility: hidden;
}
父元素添加 class="clearfix" 即可。
3. margin 垂直合并(外边距塌陷)
上下两个块元素,上下 margin 会取最大值,而非相加。
css
.top {
margin-bottom: 30px;
}
.bottom {
margin-top: 20px;
}
/* 最终间距:30px */
✅ 避坑:统一只使用 margin-bottom 控制间距。
4. 行内元素垂直内外边距失效
span、a 行内元素:
- 水平
margin / padding生效 - 垂直
margin / padding不生效
css
span {
padding-top: 10px; /* 无效 */
}
✅ 解决:添加 display: inline-block;
5. z-index 层级不生效
- z-index 必须配合定位 :
relative / absolute / fixed / sticky - 受父级层叠上下文限制,父级层级低,子级再大也没用
css
.box {
z-index: 9999; /* 无效,无定位 */
}
/* 正确 */
.box {
position: relative;
z-index: 9999;
}
三、JavaScript 核心易错点
1. var /let/const 区别与暂时性死区
js
console.log(a); // undefined 变量提升
var a = 10;
console.log(b); // 直接报错 暂时性死区
let b = 20;
✅ 开发规范:
- 常量用
const - 需修改变量用
let - 彻底弃用 var
2. == 隐式类型转换陷阱
js
console.log(0 == false); // true
console.log('' == 0); // true
console.log(null == undefined); // true
✅ 强制规范:全部使用 === 严格相等,杜绝隐式转换。
3. 引用类型浅拷贝污染
对象、数组为引用类型,直接赋值会共用同一内存地址。
js
let arr1 = [1,2,3];
let arr2 = arr1;
arr2.push(4);
console.log(arr1); // [1,2,3,4] 原数组被篡改
快速拷贝方案
js
// 数组浅拷贝
let arr2 = [...arr1];
// 对象浅拷贝
let obj2 = {...obj1};
// 简单深拷贝
let newObj = JSON.parse(JSON.stringify(oldObj));
4. 宏任务与微任务执行顺序
执行顺序:同步代码 → 微任务 → 宏任务
- 微任务:Promise.then、async/await
- 宏任务:setTimeout、定时器、DOM 渲染
js
console.log(1);
setTimeout(() => console.log(2), 0);
Promise.resolve().then(() => console.log(3));
// 输出顺序:1 → 3 → 2
5. this 指向问题
- 普通函数:this 指向调用者
- 箭头函数:无独立 this,继承上层作用域
- 定时器普通函数:this 指向 window
js
const obj = {
fn() {
setTimeout(function() {
console.log(this); // window
})
}
}
✅ 解决:改用箭头函数保存上下文
js
setTimeout(() => {
console.log(this); // 指向 obj
})
6. forEach 无法终止循环
return 只能跳出当前项,不能终止整个循环。✅ 需要中断循环使用:for...of、some、every
js
// some 返回 true 即可终止
list.some(item => {
if(item === 2) return true;
})
7. localStorage 只能存储字符串
js
// 错误
localStorage.setItem('user', {name: '张三'});
// 正确
localStorage.setItem('user', JSON.stringify({name: '张三'}));
const user = JSON.parse(localStorage.getItem('user'));
四、Vue3 项目高频易错点
1. 直接修改数组 / 对象,视图不更新
Vue 响应式依赖代理监听,直接下标修改、新增对象属性不会触发更新。
js
// 错误
list[0] = 100;
info.age = 20;
✅ 正确写法
js
// 数组替换
list.value[0] = 100
// 或使用 解构重新赋值
list.value = [...list.value]
// 对象新增属性
info.value = {...info.value, age: 20}
2. v-for 的 key 使用 index
html
预览
<!-- 不推荐:index 作为key,列表增删会DOM错乱 -->
<div v-for="(item, index) in list" :key="index"></div>
<!-- 推荐:使用唯一id -->
<div v-for="item in list" :key="item.id"></div>
3. 解构 props 丢失响应式
js
// 错误:解构后失去响应式
const { name } = props
// 正确:保留响应式
const name = computed(() => props.name)
五、写在最后
以上都是日常开发、接口联调、页面适配中最高频的低级错误,很多时候 Bug 难排查,不是技术不行,而是基础细节不注意。
建议收藏本文,开发遇到样式异常、数据不更新、异步错乱时,快速对照排查,极大提升排错效率。