Axios 把 API 封装好了,数据能拿能发,但页面总是一副「程序员审美」。
不是你不会写 CSS——而是没人想花一下午调一个弹窗的动画曲线。
UI 组件库就是干这个的:帮你把时间花在逻辑上,而不是样式上。
Element Plus 是什么
Element Plus 是 Vue 3 生态最主流的 UI 组件库,Element UI(Vue 2 版)的升级版。
提供了一整套现成的组件:
• 布局:Container、Header、Aside • 数据展示:Table、Tag、Card • 表单:Form、Input、Select、DatePicker • 反馈:Dialog、Message、MessageBox、Loading
装上就能用,不用自己写样式。
安装
npm install element-plus
然后在 main.js 里全局注册:
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')注册完后,所有 .vue 文件里可以直接用组件标签,不需要额外 import。
注意: 全局注册虽然方便,但会把所有组件都打进包里。生产环境推荐用「按需导入」——装
unplugin-vue-components插件,只注册用到的组件,包体积能小一半以上。但开发阶段全局注册最快,先用着。
从表格开始
之前我们用 v-for 渲染文章列表,每一行自己写 div、自己配 hover 效果。换成 el-table 是这样的:
<el-table :data="books" stripe style="width: 100%">
<el-table-column prop="id" label="ID" width="80" />
<el-table-column prop="title" label="标题" />
<el-table-column prop="body" label="内容" show-overflow-tooltip />
<el-table-column label="操作" width="180">
<template #default="scope">
<el-button size="small" @click="getDetail(scope.row.id)">查看</el-button>
<el-button size="small" @click="editBook(scope.row)">编辑</el-button>
<el-button size="small" type="danger" @click="delBook(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>几件事自动搞定了:
• 表格布局、斑马纹( stripe)• 内容溢出自动截断( show-overflow-tooltip,鼠标悬停显示全文)• 操作列的按钮组
不用写任何 CSS。
作用域插槽
这里有个重要的写法:#default="scope"。
el-table-column 渲染每一行时,会把当前行的数据传出来。scope.row 就是当前行对象,scope.row.id 就是当前行的 ID。
这个模式叫「作用域插槽」,是组件给你开的一个口子,让你能自定义这块内容的渲染方式。类比 Java 的 forEach 回调——遍历到当前元素时告诉你「这是当前的数据,你看着办」。
弹窗(Dialog)
管理后台少不了弹窗。新增、编辑、确认删除,都需要。
el-dialog 基本用法:
<el-dialog v-model="dialogVisible" title="新增" width="500px">
<!-- 表单内容 -->
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="onSubmit">确定</el-button>
</template>
</el-dialog>和 v-model 绑定一个布尔值,控制显隐。#footer 插槽用来放底部按钮。
表单(Form)
表单组件配合 v-model 绑定数据:
<el-form :model="bookForm" label-width="auto">
<el-form-item label="标题">
<el-input v-model="bookForm.title" placeholder="请输入标题" />
</el-form-item>
<el-form-item label="内容">
<el-input v-model="bookForm.body" type="textarea" :rows="4" />
</el-form-item>
</el-form>:model 绑定整个表单数据对象,v-model 绑定具体字段,双向同步。
弹窗确认(MessageBox)
删除操作不能手滑,需要二次确认。ElMessageBox.confirm 弹一个原生风格的确认框:
import { ElMessageBox, ElMessage } from'element-plus'
consthandleDelete = (row) => {
ElMessageBox.confirm(
`确定删除「${row.title}」吗?`,
'提示',
{ type: 'warning', confirmButtonText: '确定', cancelButtonText: '取消' }
).then(() => {
books.value = books.value.filter(b => b.id !== row.id)
ElMessage.success('删除成功')
}).catch(() => {
// 用户点了取消,什么都不做
})
}confirm 返回 Promise,点「确定」走 .then,点「取消」走 .catch。
CRUD 完整流程
把上面几个组件组合起来,就是一个完整的管理后台:
JS 逻辑也很清晰——新增/编辑的提交函数:
const onSubmit = () => {
if (!bookForm.value.title || !bookForm.value.body) {
ElMessage.warning('请填写完整信息')
return
}
if (bookForm.value.id) {
// 编辑
const idx = books.value.findIndex(b => b.id === bookForm.value.id)
books.value[idx] = { ...books.value[idx], ...bookForm.value }
ElMessage.success('修改成功')
} else {
// 新增
books.value.unshift({ ...bookForm.value, id: Date.now() })
ElMessage.success('新增成功')
}
dialogVisible.value = false
}区分新增和编辑,靠的是 bookForm.id 有没有值。
踩坑记录
几个初学者容易碰到的:
1. 组件 import 了但报 unknown html tag
检查 main.js 有没有调用 app.use(ElementPlus)。全局注册后不需要每个组件手动 import(但不是所有版本都自动注册所有组件,个别组件如 ElMessageBox 需要显式 import)
2. v-model 绑的变量没定义v-model="book.title" 但 book 没声明 ref,会报 undefined。先 const book = ref({})。
3. lable 写成了 lableel-table-column 的 label 属性拼错了不会报错,只是列头不显示。
4. ElMessage 不弹出
ElMessage 不是标签,是函数调用。在 <script setup> 里 import 后直接调用 ElMessage.success('xxx')。注意不要放在 <template> 里。
小结
UI 组件库的本质是约定大于配置——你按它的规则写,它帮你搞定样式和交互。
Element Plus 并不能让你不写 CSS,但能让你少写 80% 的 CSS。表格、弹窗、表单、消息提示这些高频组件,点两下就能用,省下来的时间够调两天接口了。
关于按需导入(进阶):
全局注册会把 Element Plus 所有组件都打进包,体积大约 800KB+。如果在意包体积,可以用 unplugin-vue-components 插件实现按需导入:
1. 装插件 2. vite.config.js 加 ElementPlusResolver()3. main.js 去掉 app.use(ElementPlus)和 CSS 引入4. 各组件里按需 import 需要的组件
项目小的时候区别不大,项目大了能省一半体积。