同学们好,我是 Eugene(尤金),一个拥有多年中后台开发经验的前端工程师~
(Eugene 发音很简单,/juːˈdʒiːn/,大家怎么顺口怎么叫就好)
你是否也有过:明明学过很多技术,一到关键时候却讲不出来、甚至写不出来?
你是否也曾怀疑自己,是不是太笨了,明明感觉会,却总差一口气?
就算想沉下心从头梳理,可工作那么忙,回家还要陪伴家人。
一天只有24小时,时间永远不够用,常常感到力不从心。
技术行业,本就是逆水行舟,不进则退。
如果你也有同样的困扰,别慌。
从现在开始,跟着我一起心态归零 ,利用碎片时间,来一次彻彻底底的基础扫盲。
这一次,我们一起慢慢来,扎扎实实变强。
不搞花里胡哨的理论堆砌,只分享看得懂、用得上的前端干货,
咱们一起稳步积累,真正摆脱"面向搜索引擎写代码"的尴尬。
一、选型与定位
- Element Plus:面向 Vue 3 + TypeScript 的 UI 组件库,适合管理后台、中台、后台系统。
- 为什么用组件库而不是手写? 统一规范、减少重复开发、内置表单校验、表格、弹窗等常见能力。
- 本文涉及组件:Form、Table、Dialog、Message/MessageBox、Upload。
二、表单 Form:数据收集与校验
2.1 核心概念
Form 的作用:收集、校验、提交 数据,包含输入框、选择器、日期等。
表单的三层结构:
- el-form:表单容器,绑定数据和校验规则
- el-form-item:单个表单项,承载 label、校验、布局
- el-input / el-select 等:具体输入控件
2.2 正确用法示例
html
<template>
<el-form
ref="formRef"
:model="form"
:rules="rules"
label-width="100px"
@submit.prevent
>
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" placeholder="请输入用户名" />
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="form.password" type="password" placeholder="请输入密码" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSubmit">提交</el-button>
<el-button @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
</template>
<script setup>
import { ref, reactive } from 'vue'
const formRef = ref()
const form = reactive({
username: '',
password: ''
})
// 校验规则:字段名要与 form 中的属性、el-form-item 的 prop 完全一致
const rules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, message: '密码至少 6 位', trigger: 'blur' }
]
}
const handleSubmit = async () => {
// validate 返回 Promise,通过则无参数,失败则返回校验错误
try {
await formRef.value.validate()
console.log('校验通过,提交数据:', form)
// 这里调用接口提交
} catch (error) {
console.log('校验失败')
}
}
const handleReset = () => {
formRef.value.resetFields()
}
</script>
说明要点:
:model="form"绑定表单数据,注意是 :model ,不是v-model:rules="rules"绑定校验规则prop="username"绑定到表单项,用于关联 rules 中的字段@submit.prevent防止回车键意外提交表单
2.3 常见踩坑
| 坑 | 错误写法 | 正确写法 |
|---|---|---|
| Form 绑定 | v-model="form" |
:model="form" |
| 不写 prop | <el-form-item> 无 prop |
<el-form-item prop="username"> |
| prop 写错位置 | 写在 el-input 上 |
必须写在 el-form-item 上 |
| prop 与 rules 不一致 | rules 里是 name,prop 是 username |
两者字段名完全一致 |
记住:el-form 用 :model、el-form-item 必须有 prop、prop 与 rules 字段名一致。
2.4 常用 API
validate():整表校验validateField(prop):校验单个字段resetFields():重置表单clearValidate():清除校验状态
三、表格 Table:列表展示
3.1 核心概念
Table 用于展示列表数据,支持排序、分页、选择、展开等。
3.2 基础用法示例
html
<template>
<el-table
:data="tableData"
stripe
border
style="width: 100%"
@selection-change="handleSelectionChange"
>
<!-- 多选列 -->
<el-table-column type="selection" width="55" />
<!-- 普通列 -->
<el-table-column prop="name" label="姓名" width="120" />
<el-table-column prop="age" label="年龄" width="80" />
<el-table-column prop="address" label="地址" show-overflow-tooltip />
<!-- 自定义列 -->
<el-table-column label="状态" width="100">
<template #default="{ row }">
<el-tag :type="row.status === 1 ? 'success' : 'info'">
{{ row.status === 1 ? '启用' : '禁用' }}
</el-tag>
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column label="操作" width="180" fixed="right">
<template #default="{ row }">
<el-button link type="primary" @click="handleEdit(row)">编辑</el-button>
<el-button link type="danger" @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script setup>
import { ref } from 'vue'
const tableData = ref([
{ id: 1, name: '张三', age: 28, address: '上海市浦东新区某某路100号', status: 1 },
{ id: 2, name: '李四', age: 32, address: '北京市朝阳区某某大街200号', status: 0 }
])
const handleSelectionChange = (selection) => {
console.log('选中的行:', selection)
}
const handleEdit = (row) => {
console.log('编辑', row)
}
const handleDelete = (row) => {
console.log('删除', row)
}
</script>
说明要点:
:data绑定数据数组,每一行是一个对象prop对应数据字段名,决定显示哪个字段show-overflow-tooltip:内容过长时显示省略号并悬浮显示完整内容#default="{ row }":插槽提供当前行数据
3.3 配置选型建议
| 场景 | 推荐配置 |
|---|---|
| 数据较多 | 加 height 或 max-height 固定高度,出现纵向滚动 |
| 树形数据 | 使用 row-key + tree-props |
| 需要合计 | show-summary + summary-method |
| 列宽不稳定 | 设置 width 或 min-width,避免抖动 |
| 多选 | type="selection" + @selection-change |
3.4 常见踩坑
- 表格数据不更新 :确保
tableData是响应式的(如ref),修改后要触发更新 - 树形表格 :必须设置
row-key为唯一字段(如id) - 固定列 :
fixed="right"或fixed="left"时,注意右侧固定列写在最后
四、弹窗 Dialog:模态对话框
4.1 核心概念
Dialog 用于在保留当前页面的前提下,弹出一个模态层展示内容,常用于表单弹窗、详情、确认等。
4.2 基础用法示例
html
<template>
<el-button @click="dialogVisible = true">打开弹窗</el-button>
<el-dialog
v-model="dialogVisible"
title="编辑用户"
width="500px"
:close-on-click-modal="false"
:before-close="handleBeforeClose"
@opened="handleOpened"
>
<!-- 弹窗内容 -->
<el-form ref="formRef" :model="form" :rules="rules">
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleConfirm">确定</el-button>
</template>
</template>
</el-dialog>
</template>
<script setup>
import { ref, reactive, watch } from 'vue'
const dialogVisible = ref(false)
const formRef = ref()
const form = reactive({ username: '' })
const rules = { username: [{ required: true, message: '请输入用户名', trigger: 'blur' }] }
// 弹窗关闭前:可做二次确认、校验等
const handleBeforeClose = (done) => {
// 简单示例:直接关闭
done()
// 如需确认:ElMessageBox.confirm('确定关闭?').then(() => done()).catch(() => {})
}
// 弹窗打开动画结束后
const handleOpened = () => {
formRef.value?.clearValidate()
}
// 关闭时清空表单(按需)
watch(dialogVisible, (val) => {
if (!val) {
form.username = ''
}
})
const handleConfirm = async () => {
try {
await formRef.value.validate()
// 提交逻辑
dialogVisible.value = false
} catch (e) {
// 校验失败
}
}
</script>
说明要点:
v-model="dialogVisible"控制显示/隐藏:close-on-click-modal="false":点击遮罩不关闭,避免误关before-close:可做二次确认、阻止关闭#footer:自定义底部按钮
4.3 常见配置选型
| 配置 | 说明 | 建议 |
|---|---|---|
| destroy-on-close | 关闭时销毁内容 | 表单弹窗建议开启,避免数据残留 |
| close-on-click-modal | 点击遮罩关闭 | 表单弹窗建议关闭 |
| append-to-body | 挂载到 body | 有嵌套弹窗时建议开启 |
五、消息 Message 与 MessageBox
5.1 ElMessage:轻量提示
用于操作后的简单反馈(成功、失败、警告等),通常显示几秒后自动消失。
javascript
import { ElMessage } from 'element-plus'
// 成功
ElMessage.success('保存成功')
// 错误
ElMessage.error('保存失败,请重试')
// 警告
ElMessage.warning('请先填写必填项')
// 自定义
ElMessage({
message: '操作成功',
type: 'success',
duration: 3000,
showClose: true
})
5.2 ElMessageBox:确认与输入
用于需要用户确认或输入的场景,比 Dialog 更轻量。
javascript
import { ElMessageBox } from 'element-plus'
// 确认删除
const handleDelete = async (row) => {
try {
await ElMessageBox.confirm(
`确定要删除「${row.name}」吗?`,
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
)
// 用户点击确定
await deleteApi(row.id)
ElMessage.success('删除成功')
} catch (e) {
// 用户点击取消或关闭
}
}
// 简单提示(类似 alert)
ElMessageBox.alert('操作完成', '提示')
5.3 选型建议
| 场景 | 用 Message | 用 MessageBox |
|---|---|---|
| 保存成功、失败提示 | ✅ | |
| 删除前确认 | ✅ | |
| 需要用户输入 | ✅(prompt) | |
| 复杂表单、多内容 | 改用 Dialog |
六、上传 Upload:文件上传
6.1 核心概念
Upload 支持自动上传和手动上传:自动上传是选完即传,手动上传是选完后由按钮触发上传。
6.2 自动上传(选完即传)
html
<template>
<el-upload
action="/api/upload"
:headers="uploadHeaders"
:on-success="handleSuccess"
:on-error="handleError"
:before-upload="beforeUpload"
>
<el-button type="primary">点击上传</el-button>
</el-upload>
</template>
<script setup>
import { reactive } from 'vue'
// 请求头,常用于 Token
const uploadHeaders = reactive({
Authorization: `Bearer ${localStorage.getItem('token')}`
})
// 上传前:校验格式、大小
const beforeUpload = (file) => {
const isJPG = file.type === 'image/jpeg' || file.type === 'image/png'
const isLt2M = file.size / 1024 / 1024 < 2
if (!isJPG) {
ElMessage.error('只能上传 JPG/PNG 格式')
return false // 阻止上传
}
if (!isLt2M) {
ElMessage.error('图片大小不能超过 2MB')
return false
}
return true
}
const handleSuccess = (response, file, fileList) => {
ElMessage.success('上传成功')
// response 一般为后端返回的 URL 等
}
const handleError = () => {
ElMessage.error('上传失败')
}
</script>
6.3 手动上传(和表单一起提交)
html
<template>
<el-form :model="form">
<el-form-item label="附件">
<el-upload
ref="uploadRef"
:auto-upload="false"
:limit="3"
:on-exceed="handleExceed"
:on-change="handleChange"
>
<el-button type="primary">选择文件</el-button>
</el-upload>
</el-form-item>
<el-button @click="submitForm">提交表单(含文件)</el-button>
</el-form>
</template>
<script setup>
import { ref } from 'vue'
const uploadRef = ref()
const form = ref({ files: [] })
// 手动上传时,选中的文件会进入 fileList,需要自己调用接口上传
const handleChange = (file, fileList) => {
form.value.files = fileList
}
const handleExceed = () => {
ElMessage.warning('最多上传 3 个文件')
}
const submitForm = async () => {
const formData = new FormData()
form.value.files.forEach(f => {
formData.append('files', f.raw)
})
// 再 append 其他表单字段...
// await uploadApi(formData)
}
</script>
说明要点:
:auto-upload="false"关闭自动上传on-change拿到选中的文件列表- 手动上传时用
FormData组装并调用自己的接口
6.4 常见踩坑
| 坑 | 原因 | 处理 |
|---|---|---|
| before-upload 返回 false 仍上传 | 理解错误 | 返回 false 或 Promise.reject() 会阻止上传 |
| 上传后列表不更新 | 未绑定 file-list | 用 v-model:file-list 或 :file-list 绑定 |
| 跨域、Cookie | 未带凭证 | 设置 :with-credentials="true" |
| 需要 Token | 接口要鉴权 | 通过 :headers 传入 |
七、小结
- Form :用
:model+prop+rules,三者字段名一致 - Table :
prop对数据字段,复杂展示用#default插槽 - Dialog :用
v-model控制显隐,表单弹窗建议destroy-on-close - Message :轻量提示;MessageBox:确认、输入
- Upload :自动上传用
action+ 钩子;手动上传用:auto-upload="false"+ 自定义提交
按上述方式选型和编码,可以避开大部分常见坑。如果你希望我按某一块(比如 Form、Table、Upload)再单独细化成一篇更长的教程,可以说明一下侧重点(例如:复杂表单、动态表格、多图上传等)。
学习本就是一场持久战,不需要急着一口吃成胖子。哪怕今天你只记住了一点点,这都是实打实的进步。
后续我还会继续用这种大白话、讲实战方式,带大家扫盲更多前端基础。
关注我,不迷路,咱们把那些曾经模糊的知识点,一个个彻底搞清楚。
如果你觉得这篇内容对你有帮助,不妨点赞+收藏,下次写代码卡壳时,拿出来翻一翻,比搜引擎更靠谱。
我是 Eugene,你的电子学友,我们下一篇干货见~