第 23 章:Element Plus 实战
学习目标
- 用 el-table 加分页和搜索
- 用 el-form 写表单
- 自定义 el-table 列渲染
- 避坑:表格性能和 slot 类型
一、table + 分页
vue
<template>
<el-input v-model="keyword" placeholder="搜索" clearable />
<el-button type="primary" @click="load">查询</el-button>
<el-table :data="list" v-loading="loading" border>
<el-table-column prop="id" label="ID" width="80" />
<el-table-column prop="name" label="姓名" />
<el-table-column label="操作" width="200">
<template #default="{ row }">
<el-button size="small" @click="edit(row)">编辑</el-button>
<el-button size="small" type="danger" @click="remove(row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="page"
v-model:page-size="pageSize"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="load"
/>
</template>ts
const keyword = ref('')
const list = ref<User[]>([])
const total = ref(0)
const page = ref(1)
const pageSize = ref(20)
const loading = ref(false)
const load = async () => {
loading.value = true
const res = await userApi.list({ keyword: keyword.value, page: page.value, pageSize: pageSize.value })
list.value = res.items
total.value = res.total
loading.value = false
}⚠️ 坑 1:大数据表格要
virtual-list,设置el-table-v2,否则 1 万行卡死。
二、自定义列渲染
vue
<el-table-column label="状态">
<template #default="{ row }">
<el-tag :type="row.status === 1 ? 'success' : 'danger'">
{{ row.status === 1 ? '启用' : '禁用' }}
</el-tag>
</template>
</el-table-column>vue
<el-table-column label="头像">
<template #default="{ row }">
<el-avatar :src="row.avatar" />
</template>
</el-table-column>三、Dialog + Form
vue
<template>
<el-dialog v-model="visible" title="编辑用户" width="500px">
<el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-switch v-model="form.status" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="submit">保存</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
const formRef = ref<FormInstance>()
const form = reactive({ name: '', status: true })
const rules: FormRules = {
name: [{ required: true, message: '必填' }],
}
const submit = async () => {
await formRef.value?.validate()
await userApi.save(form)
visible.value = false
load()
}
</script>四、菜单 + 面包屑
vue
<el-menu :default-active="route.path" router>
<el-menu-item index="/home">首页</el-menu-item>
<el-menu-item index="/users">用户</el-menu-item>
</el-menu>vue
<el-breadcrumb>
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>{{ route.meta.title }}</el-breadcrumb-item>
</el-breadcrumb>五、消息 & 通知
ts
import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
ElMessage.success('保存成功')
ElMessageBox.confirm('确定删除?', '提示', { type: 'warning' })
.then(() => ElMessage.success('已删除'))
ElNotification({ title: '通知', message: '新订单', type: 'success' })⚠️ 坑 2:ElMessageBox 链式
.then之前的链上必须 catch,否则 unhandled rejection。
六、主题定制
ts
// styles/element.scss
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
$colors: (
'primary': ('base': #42b883),
),
);ts
// vite.config.ts
css: {
preprocessorOptions: {
scss: { additionalData: `@use "@/styles/element.scss" as *;` },
},
}七、本章小结
| 组件 | 用途 |
|---|---|
el-table + el-pagination | 列表 |
el-dialog + el-form | 表单 |
el-menu | 菜单 |
el-message | 消息 |
| 主题 SCSS | 全局定制 |
动手练习
- 用户列表:table + 分页 + 搜索
- 编辑表单:dialog + form + 校验
- 确认弹窗:删除前
ElMessageBox.confirm
下一章:第 24 章:表单与校验 →