Article

组件库 Element Plus

更新于:2026-07-11

第一章:Element Plus 入门与环境搭建

1.1 什么是 Element Plus

概念名称说明注意事项
Element Plus基于 Vue 3 的桌面端组件库,是 Element UI 的升级版本,提供丰富的 UI 组件,支持 TypeScript、暗色主题、国际化等特性。仅适用于 Vue 3 项目,不兼容 Vue 2。
设计理念一致、反馈、效率、可控,遵循 Material Design 设计规范。适合中后台管理系统快速开发。
开源协议MIT 协议,可免费用于商业项目。需保留版权声明。
官方网站https://element-plus.org

1.2 支持的环境与浏览器兼容性

环境类型支持情况注意事项
Vue.js 版本Vue 3.0+不支持 Vue 2.x
浏览器支持现代浏览器(Chrome、Edge、Firefox、Safari)
支持 IE11(需额外 polyfill)
若需兼容 IE11,需引入 @babel/polyfill 或使用 Vite/webpack 配置兼容性构建
构建工具支持 Vite、Webpack、Vue CLI推荐使用 Vite 提升开发体验
TypeScript原生支持 TypeScript类型定义完整,推荐在 TS 项目中使用

1.3 安装方式(npm/cdn)

安装方式语法用途注意事项
npm 安装npm install element-plus --save在 Vue 3 项目中通过包管理器安装 Element Plus需确保项目已安装 Vue 3
yarn 安装yarn add element-plus使用 yarn 包管理器安装需先安装 yarn
pnpm 安装pnpm add element-plus使用 pnpm 安装依赖更节省磁盘空间
CDN 引入通过 <script> 标签引入快速在 HTML 中使用 Element Plus仅用于学习或简单页面,不推荐生产环境使用

CDN 引入 - 代码示例:

<script src="https://unpkg.com/vue@3"></script>
<script src="https://unpkg.com/element-plus"></script>

npm 安装 - 代码示例:

npm install element-plus --save

yarn 安装 - 代码示例:

yarn add element-plus

pnpm 安装 - 代码示例:

pnpm add element-plus

1.4 在 Vue 3 项目中引入 Element Plus(完整引入/按需引入)

完整引入

引入方式语法用途注意事项
main.js 中引入import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus)
全量引入所有组件和样式打包体积较大,适合快速开发原型

完整引入 - 代码示例:

import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')

按需引入(推荐)

引入方式语法用途注意事项
手动按需引入import { ElButton, ElInput } from 'element-plus'
import 'element-plus/theme-chalk/el-button.css'
只引入用到的组件和样式需手动管理样式引入,较繁琐
自动按需引入(推荐)结合 unplugin-vue-componentsunplugin-auto-import自动按需引入组件和 API需正确配置构建工具,可大幅减少打包体积

手动按需引入 - 代码示例:

import { createApp } from 'vue'
import App from './App.vue'
import { ElButton, ElInput } from 'element-plus'
import 'element-plus/theme-chalk/el-button.css'
import 'element-plus/theme-chalk/el-input.css'

const app = createApp(App)
app.component(ElButton.name, ElButton)
app.component(ElInput.name, ElInput)
app.mount('#app')

自动按需引入 - 安装依赖:

npm install -D unplugin-vue-components unplugin-auto-import

自动按需引入 - Vite 配置:

import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default {
  plugins: [
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
}

1.5 初识全局配置(size、zIndex 等)

配置项语法用途注意事项
sizeapp.use(ElementPlus, { size: 'small' })设置全局组件默认尺寸可被组件自身 size 属性覆盖
zIndexapp.use(ElementPlus, { zIndex: 3000 })设置弹层类组件的起始 zIndex用于避免与其他 UI 库或样式层叠冲突
localeapp.use(ElementPlus, { locale: zhCn })设置全局语言(国际化)需额外引入 locale 包
messageBoxapp.use(ElementPlus, { appendToBody: true })控制 MessageBox、Message 等是否挂载到 body防止被父级 overflow: hidden 影响显示

全局配置 - 代码示例:

const app = createApp(App)
app.use(ElementPlus, { size: 'medium' })
// 可选值:'large', 'default', 'small'

zIndex 配置 - 代码示例:

app.use(ElementPlus, { zIndex: 2000 })

locale 配置 - 代码示例:

import { zhCn } from 'element-plus/es/locale'
app.use(ElementPlus, { locale: zhCn })

messageBox 配置 - 代码示例:

app.use(ElementPlus, { appendToBody: true })

第二章:基础样式与通用组件

2.1 布局:Container 布局容器

组件名说明注意事项
<el-container>外层容器,可嵌套 header、aside、main、footer必须包含至少一个子组件
<el-header>顶部区域可设置 height,默认 60px
<el-aside>侧边栏区域width 可设为具体值(如 200px)或百分比
<el-main>主内容区域默认占据剩余空间
<el-footer>底部区域可设置 height,默认 60px

布局组合示例:

  • 上中下:<el-container><el-header><el-main><el-footer>
  • 左侧边栏+主内容:<el-container><el-aside><el-main>
  • 上+左+主+下:嵌套使用 <el-container>

Container 布局 - 代码示例:

<el-container>
  <el-header>Header</el-header>
  <el-main>Main</el-main>
</el-container>

侧边栏布局 - 代码示例:

<el-container>
  <el-aside>Aside</el-aside>
  <el-main>Main Content</el-main>
</el-container>

完整布局 - 代码示例:

<el-container>
  <el-header>Header</el-header>
  <el-container>
    <el-aside>Aside</el-aside>
    <el-main>Main Content</el-main>
  </el-container>
  <el-footer>Footer</el-footer>
</el-container>

2.2 布局:Layout 布局(Row 与 Col)

<el-row> 属性

属性类型说明注意事项
gutterNumber栅格间隔(px)实际间隔为 gutter/2 + gutter/2
justifyString水平排列方式(start, center, end, space-between, space-around)类似 flex 布局 justify-content
alignString垂直对齐方式(top, middle, bottom)类似 flex 布局 align-items
tagString自定义元素标签名默认为 div

<el-col> 属性

属性类型说明
spanNumber占据的栅格数(1–24)
offsetNumber左侧偏移栅格数
pushNumber向右移动栅格数
pullNumber向左移动栅格数
xs[Object, Number]响应式:超小屏幕 (<768px)
sm[Object, Number]响应式:小屏幕 (≥768px)
md[Object, Number]响应式:中等屏幕 (≥992px)
lg[Object, Number]响应式:大屏幕 (≥1200px)
xl[Object, Number]响应式:超大屏幕 (≥1920px)

Layout 布局 - 代码示例:

<el-row :gutter="20">
  <el-col :span="8">col</el-col>
  <el-col :span="8">col</el-col>
</el-row>

<el-row justify="center">
  <el-col :span="8">居中排列</el-col>
</el-row>

<el-row align="middle">
  <el-col :span="8">垂直居中</el-col>
</el-row>

2.3 颜色、字体、边距等基础样式类

文字颜色

类名说明注意事项
text-primary主要文本颜色用于强调重要信息
text-success成功状态颜色绿色
text-warning警告状态颜色黄色
text-danger危险状态颜色红色
text-info信息状态颜色灰色

背景颜色

类名说明注意事项
bg-primary主要背景色搭配白色文字
bg-success ~ bg-info对应状态背景注意文字可读性

字体大小

类名说明注意事项
text-xs ~ text-xl超小到超大字体基于 rem 单位

字体粗细

类名说明注意事项
font-bold加粗对应 font-weight: 700
font-normal正常font-weight: 400

边距与内边距

类名说明注意事项
m-1 ~ m-5外边距,1=4px支持 mt-, mr-, mb-, ml- 方向控制
p-1 ~ p-5内边距支持 pt-, pr-, pb-, pl-

文本对齐

类名说明注意事项
text-left左对齐默认行为
text-center居中对齐常用于标题
text-right右对齐用于操作列对齐

2.4 辅助类(隐藏、显示、文字对齐等)

类名说明注意事项
hidden隐藏元素(display: none不占据布局空间
block显示为块级元素常用于响应式切换
inline-block内联块用于按钮组等布局
flex启用 Flex 布局子元素可使用 flex 子项类
items-centerflex 项目垂直居中需配合 flex 使用
justify-centerflex 项目水平居中类似 justify="center"
overflow-hidden隐藏溢出内容防止内容溢出容器
rounded添加圆角(4px)按钮、卡片常用
rounded-full完全圆形(50%)适合头像
shadow添加阴影提升层级感
cursor-pointer鼠标指针为手型提示用户可交互

第三章:表单组件(Form Components)

3.1 Form 表单容器

参数

参数类型说明注意事项
modelObject表单数据对象必须绑定一个对象用于存储字段值
rulesObject表单验证规则配合 el-form-item 和 prop 使用
label-widthString / Number标签宽度可设为 'auto' 或具体数值
label-positionString标签位置(top, left, right)默认为 right
inlineBoolean是否为行内表单表单项水平排列,适合搜索表单
sizeString控件尺寸(large, default, small)可被子组件继承

方法

方法语法用途注意事项
validatevalidate(callback: Function)触发全局表单验证callback 接收 boolean 参数
validateFieldvalidateField(props: string | array, callback: Function)验证指定字段用于局部验证
resetFieldsresetFields()重置所有字段为初始值需先设置 ref="form"
clearValidateclearValidate(props?: string | array)清除验证结果可传字段名清除特定项

validate 方法 - 代码示例:

this.$refs.form.validate(valid => {
  if (valid) console.log('验证通过')
})

validateField 方法 - 代码示例:

this.$refs.form.validateField('name', msg => {
  if (!msg) console.log('name 有效')
})

resetFields 方法 - 代码示例:

this.$refs.form.resetFields()

clearValidate 方法 - 代码示例:

this.$refs.form.clearValidate()

3.2 Input 输入框

参数

参数类型说明注意事项
v-modelString / Number绑定值必须使用
typeString输入框类型(text, password, textarea 等)支持原生 input 类型
placeholderString占位提示文字提升用户体验
disabledBoolean是否禁用禁用后无法输入
clearableBoolean是否可清空仅适用于单行输入框
show-passwordBoolean显示切换密码图标用于 password 类型
prefix-iconString前缀图标类名需引入图标组件
suffix-iconString后缀图标类名
rowsNumbertextarea 行数仅 textarea 有效
autosizeBoolean / Object自适应高度(textarea)避免滚动条突兀出现

事件

事件回调参数说明
input(value: string | number)输入时触发
change(value: string | number)值改变且失焦时触发
focus(event: Event)获得焦点时触发
blur(event: Event)失去焦点时触发
clear清空时触发(clearable)

插槽

插槽说明
prefix自定义前缀内容
suffix自定义后缀内容
prepend前置内容(配合 input-group)
append后置内容(配合 input-group)

基本用法 - 代码示例:

<el-input v-model="inputValue" placeholder="请输入内容" clearable></el-input>

密码输入框 - 代码示例:

<el-input v-model="password" type="password" show-password></el-input>

textarea - 代码示例:

<el-input v-model="textarea" type="textarea" :rows="4" :autosize="{ minRows: 2, maxRows: 6 }"></el-input>

复合输入框 - 代码示例:

<el-input v-model="url">
  <template #prepend>Http://</template>
  <template #append>.com</template>
</el-input>

3.3 InputNumber 数字输入框

参数

参数类型说明注意事项
v-modelNumber绑定数值必须为数字类型
minNumber最小值超出限制无法输入
maxNumber最大值
stepNumber步长支持小数步长
disabledBoolean是否禁用
controlsBoolean是否显示加减按钮可隐藏按钮
controls-positionString按钮位置(right)仅支持 right
precisionNumber数值精度保留小数位数,超出会四舍五入

事件

事件回调参数说明
change(currentVal, oldVal)数值改变时触发
focus(event)获得焦点时触发
blur(event)失去焦点时触发

方法

方法语法说明
focusfocus()使输入框获得焦点
blurblur()使输入框失去焦点

InputNumber - 代码示例:

<el-input-number v-model="num" :min="0" :max="100" :step="0.1" :precision="2"></el-input-number>

3.4 Select 选择器

参数

参数类型说明注意事项
v-modelString / Number / Array选中值多选时为数组
multipleBoolean是否多选开启后 v-model 应为数组
disabledBoolean是否禁用
clearableBoolean是否可清空单选时有效
filterableBoolean是否可搜索搜索选项文本
remoteBoolean是否为远程搜索配合 remote-method 使用
remote-methodFunction远程搜索方法接收输入关键词
loadingBoolean是否加载中显示加载动画
loading-textString加载时显示文字默认为 “加载中”

事件

事件回调参数说明
change(value)值改变时触发
visible-change(visible)下拉框展开/收起时触发
remove-tag(tag)多选时删除 tag 时触发
clear清空时触发
focus(event)获得焦点
blur(event)失去焦点

插槽

插槽说明
default自定义下拉选项内容
prefix前缀图标
empty无选项时显示内容

选项数据格式 - 代码示例:

options: [
  { value: 1, label: '选项1' },
  { value: 2, label: '选项2' }
]

Select - 代码示例:

<el-select v-model="selected" filterable remote :remote-method="querySearch" :loading="loading" loading-text="加载中...">
  <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>

3.5 Radio 单选框

参数

参数类型说明注意事项
v-modelString / Number / Boolean绑定值必须绑定
labelString / Number / BooleanRadio 的 value 值与 v-model 比较是否选中
disabledBoolean是否禁用
borderBoolean是否显示边框常用于按钮样式

事件

事件回调参数说明
change(value)值改变时触发

组件

组件说明
<el-radio>单个单选框
<el-radio-group>单选框组,用于包裹多个 radio
<el-radio-button>按钮样式单选框

Radio 单选框 - 代码示例:

<el-radio-group v-model="radio">
  <el-radio :label="1">选项1</el-radio>
  <el-radio :label="2">选项2</el-radio>
</el-radio-group>

3.6 Checkbox 多选框

参数

参数类型说明注意事项
v-modelArray / String / Boolean绑定值多选时通常为数组
labelString / Number / Booleancheckbox 值数组中包含 label 即为选中
true-labelString / Number选中时的值用于布尔值映射
false-labelString / Number未选中时的值
disabledBoolean是否禁用
indeterminateBoolean是否半选(仅视觉)常用于全选控制

事件

事件回调参数说明
change(value)值改变时触发

组件

组件说明
<el-checkbox>单个多选框
<el-checkbox-group>多选框组
<el-checkbox-button>按钮样式多选框

全选示例:使用 indeterminate@change 实现全选/全不选逻辑。

Checkbox - 代码示例:

<el-checkbox-group v-model="checked">
  <el-checkbox :label="1">选项1</el-checkbox>
  <el-checkbox :label="2" :disabled="true">选项2</el-checkbox>
</el-checkbox-group>

3.7 Switch 开关

参数

参数类型说明注意事项
v-modelBoolean / String / Number绑定值
active-valueString / Number / Boolean打开时的值默认为 true
inactive-valueString / Number / Boolean关闭时的值默认为 false
disabledBoolean是否禁用
widthNumber / String宽度(px)自定义开关宽度
active-textString打开时的文字
inactive-textString关闭时的文字
inline-promptBoolean文字是否在内部显示否则在右侧

事件

事件回调参数说明
change(value)值改变时触发
input(value)输入时触发

Switch - 代码示例:

<el-switch v-model="switchVal" active-text="开启" inactive-text="关闭" inline-prompt></el-switch>

3.8 Slider 滑块

参数

参数类型说明注意事项
v-modelNumber / Array当前值范围选择时为数组
minNumber最小值默认 0
maxNumber最大值默认 100
stepNumber步长决定可选值
show-stopsBoolean是否显示间断点需设置 step
show-tooltipBoolean是否显示 tooltip
rangeBoolean是否为范围选择v-model 应为数组
verticalBoolean是否竖向需设置 height
heightString竖向时高度仅 vertical 有效

事件

事件回调参数说明
change(value)值改变后触发(拖拽结束)
input(value)拖拽过程中持续触发

Slider - 代码示例:

<el-slider v-model="sliderValue" :min="0" :max="100" :step="10" show-stops></el-slider>

3.9 TimePicker 时间选择器

参数类型说明注意事项
v-modelString / Date绑定值
formatString显示格式默认 "HH:mm:ss"
value-formatString绑定值格式控制 v-model 类型
disabledBoolean是否禁用
clearableBoolean是否可清空
readonlyBoolean是否只读
is-24-hourBoolean是否 24 小时制默认 true

事件

事件说明
change值改变时触发
focus获得焦点
blur失去焦点

TimePicker - 代码示例:

<el-time-picker v-model="time" format="HH:mm:ss" value-format="HH:mm" :is-24-hour="true"></el-time-picker>

3.10 DatePicker 日期选择器

参数类型说明注意事项
v-modelString / Date绑定值
typeString选择器类型支持 year, month, week, dates 等
formatString显示格式用户看到的格式
value-formatString绑定值格式决定返回字符串还是 Date 对象
disabled-dateFunction禁用日期函数返回 true 则禁用
shortcutsArray快捷选项自定义快捷方式

shortcuts - 代码示例:

shortcuts: [{
  text: '今天',
  value: new Date()
}]

DatePicker - 代码示例:

<el-date-picker v-model="date" type="date" format="yyyy-MM-dd" value-format="yyyy-MM-dd" :disabled-date="date => date < new Date()"></el-date-picker>

3.11 DateTimePicker 日期时间选择器

参数类型说明注意事项
v-modelString / Date绑定值
typeString类型支持 datetime, datetimerange
formatString显示格式
value-formatString绑定值格式可设为 'timestamp' 返回时间戳
range-separatorString范围选择分隔符
start-placeholderString起始占位符范围选择时使用
end-placeholderString结束占位符

事件与 DatePicker 相同。

DateTimePicker - 代码示例:

<el-date-picker v-model="datetime" type="datetime" format="yyyy-MM-dd HH:mm:ss" value-format="timestamp" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间"></el-date-picker>

3.12 Upload 上传

参数

参数类型说明注意事项
actionString上传地址必填
multipleBoolean是否支持多选
disabledBoolean是否禁用
limitNumber最大允许上传数量
on-exceedFunction超出 limit 时的钩子
before-uploadFunction上传前钩子可用于校验文件
on-successFunction上传成功回调接收 response, file, fileList
on-removeFunction文件移除回调
file-listArray上传文件列表数组项包含 name, url

方法

方法说明
submit手动提交上传
clearFiles清空文件列表
abort取消上传请求

插槽

插槽说明
default触发上传的元素(如按钮)
file自定义文件列表内容

Upload - 代码示例:

<el-upload action="/upload" multiple :limit="3" :on-exceed="handleExceed" :before-upload="beforeUpload" :on-success="handleSuccess" :on-remove="handleRemove" :file-list="fileList">
  <el-button type="primary">点击上传</el-button>
</el-upload>

3.13 Rate 评分

参数类型说明注意事项
v-modelNumber绑定值
maxNumber最大分值默认 5
disabledBoolean是否只读
allow-halfBoolean是否允许半选
show-textBoolean是否显示辅助文字
textsArray辅助文字数组长度应等于 max
colorString / Array图标颜色可设渐变

事件

事件说明
change值改变时触发

Rate - 代码示例:

<el-rate v-model="rate" :max="10" allow-half show-text :texts="['极差','差','一般','好','极好']" :color="['#99A', '#4D5']"></el-rate>

3.14 ColorPicker 颜色选择器

参数类型说明注意事项
v-modelString绑定颜色值"#ff0000"
show-alphaBoolean是否支持透明度
color-formatString颜色格式支持 hsl, hsv, hex, rgb
disabledBoolean是否禁用
popper-classString下拉框类名自定义样式

事件

事件说明
change值改变时触发
active-change面板颜色改变时触发(实时)

ColorPicker - 代码示例:

<el-color-picker v-model="color" show-alpha color-format="rgb" popper-class="my-picker"></el-color-picker>

3.15 Transfer 穿梭框

参数类型说明注意事项
v-modelArray右侧列表绑定值包含 key 的数组
dataArray源数据每项需有 key, label, disabled
titlesArray两栏标题
button-textsArray按钮文字
render-contentFunction自定义渲染函数
filterableBoolean是否可搜索
filter-methodFunction自定义搜索逻辑

事件

事件说明
change右侧列表变化时触发

Transfer - 代码示例:

<el-transfer v-model="value" :data="listData" :titles="['源列表','目标列表']" :button-texts="['到左边','到右边']" :render-content="renderFunc" filterable :filter-method="customFilter"></el-transfer>

3.16 Form Validation 表单验证机制

验证规则字段

字段类型说明
requiredBoolean是否必填
messageString验证失败提示信息
triggerString / Array触发方式('blur', 'change', 'submit'
typeString数据类型(string, number, boolean, array, object, date, email, url, enum)
min / maxNumber最小/最大长度或数值
patternRegExp正则表达式校验
validatorFunction自定义验证函数

触发方式

触发方式说明
blur失去焦点时验证
change值改变时验证
submit提交时验证

自定义验证函数 - 代码示例:

const validatePass = (rule, value, callback) => {
  if (value === '') {
    callback(new Error('请输入密码'))
  } else if (value.length < 6) {
    callback(new Error('密码不能少于6位'))
  } else {
    callback()
  }
}

完整规则 - 代码示例:

rules: {
  name: [
    { required: true, message: '姓名不能为空', trigger: 'blur' },
    { min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' }
  ],
  email: [
    { type: 'email', message: '邮箱格式不正确', trigger: 'blur' }
  ]
}

第四章:数据展示组件(Data Display)

4.1 Table 表格

参数

参数类型说明注意事项
dataArray表格数据源数组中的每个对象为一行数据
borderBoolean是否显示边框默认无边框
stripeBoolean是否显示斑马纹提升可读性
sizeString尺寸(large, default, small)影响行高
heightString / Number表格高度(px)固定高度可开启纵向滚动
max-heightString / Number最大高度超出自动滚动
fitBoolean列宽度是否自适应默认 true
show-headerBoolean是否显示表头可隐藏表头
highlight-current-rowBoolean是否高亮当前行配合 @current-change 使用

事件

事件回调参数说明
selection-change(selection)多选框选中项变化时触发
current-change(currentRow, oldRow)当前行变化时触发
row-click(row, column, event)点击行时触发
cell-click(row, column, cell, event)点击单元格时触发
sort-change({ column, prop, order })排序变化时触发

方法

方法语法用途注意事项
clearSelectionclearSelection()清空多选项type="selection"
toggleRowSelectiontoggleRowSelection(row, selected)切换某行选中状态第二个参数可控制是否选中
setCurrentRowsetCurrentRow(row)设置当前行高亮指定行
clearSortclearSort()清空排序状态
doLayoutdoLayout()重新布局表格用于动态调整列宽后刷新

插槽

插槽说明
default列内容(在 el-table-column 中使用)
empty数据为空时显示内容

4.2 Tag 标签

参数类型说明注意事项
typeString类型(success, info, warning, danger)视觉区分状态
effectString主题(dark, light, plain)dark 背景深色,light 浅色
closableBoolean是否可关闭显示关闭图标
disable-transitionsBoolean是否禁用动画关闭时无淡出效果
hitBoolean是否有边框阴影视觉更突出
colorString自定义背景色覆盖默认颜色
size尺寸:large / default / small

事件

事件说明
close关闭时触发

Tag - 代码示例:

<el-tag type="danger" closable @close="handleClose">危险</el-tag>

4.3 Progress 进度条

参数类型说明注意事项
percentageNumber百分比值(必填)必须在 0-100 之间
typeString类型(line, circle, dashboard)圆形或仪表盘样式
stroke-widthNumber进度条宽度(px)默认 6
text-insideBoolean文字是否在进度条内仅 line 类型有效
statusString状态(success, exception, warning)改变颜色
indeterminateBoolean是否为不确定进度显示流动动画
durationNumber不确定进度动画时长(秒)默认 3

插槽

插槽说明
default自定义进度文字内容

Progress(圆形)- 代码示例:

<el-progress type="circle" :percentage="50"></el-progress>

4.4 Tree 树形控件

参数

参数类型说明注意事项
dataArray树节点数据每个节点含 label、children
propsObject配置字段名自定义 key 映射
default-expand-allBoolean是否默认展开所有节点性能注意大数据量
expand-on-click-nodeBoolean是否点击节点展开否则需点击箭头
check-on-click-nodeBoolean是否点击节点触发选中
node-keyString每个节点的唯一标识用于标记节点
default-expanded-keysArray默认展开的节点 key 数组node-key
default-checked-keysArray默认勾选的节点 key 数组多选时使用
show-checkboxBoolean是否显示多选框启用节点选择

事件

事件回调参数说明
node-click(data, node, vm)点击节点时触发
check-change(data, checked, indeterminate)节点选中状态变化时触发
check(data, checkedStatus)点击复选框触发
current-change(data, node)当前节点变化时触发

方法

方法语法用途
getCheckedNodesgetCheckedNodes(leafOnly, includeHalfChecked)获取已勾选节点
setCheckedNodessetCheckedNodes(nodes)设置勾选节点
getHalfCheckedNodesgetHalfCheckedNodes()获取半选中节点

data - 代码示例:

treeData: [
  { id: 1, name: '一级', children: [{ id: 2, name: '二级' }] }
]

4.5 Pagination 分页

参数

参数类型说明注意事项
current-pageNumber当前页码建议使用 v-model
page-sizeNumber每页条数
totalNumber总条数必填,用于计算总页数
page-sizesArray每页条数选项配合 sizes 使用
layoutString组件布局用逗号分隔
backgroundBoolean按钮是否带背景色视觉更明显
smallBoolean是否小型分页用于紧凑场景

事件

事件回调参数说明
size-change(newSize)每页条数改变时触发
current-change(newPage)页码改变时触发
prev-click(newPage)上一页被点击时触发
next-click(newPage)下一页被点击时触发

Pagination - 代码示例:

<el-pagination
  v-model:current-page="currentPage"
  v-model:page-size="pageSize"
  :total="100"
  :page-sizes="[10, 20, 30]"
  layout="total, sizes, prev, pager, next, jumper"
  background
  @current-change="handlePageChange"
/>

4.6 Badge 徽标数

参数类型说明注意事项
valueString / Number显示值
maxNumber最大值超出显示 ${max}+
is-dotBoolean是否小圆点仅表示有消息
hiddenBoolean是否隐藏控制显示
typeString类型(primary, success, warning, danger, info)控制颜色

插槽

插槽说明
default被徽标装饰的元素
value自定义内容显示

4.7 Avatar 头像

参数类型说明注意事项
sizeString / Number头像大小支持 large / normal / small
shapeString形状(circle, square)默认 circle
srcString图片地址
altString图片描述
fitString图片填充模式(fill, contain, cover, none, scale-down)类似 object-fit
iconString图标类名图片加载失败时显示

插槽

插槽说明
default自定义内容(文字或图标)

4.8 Skeleton 骨架屏

参数类型说明注意事项
animatedBoolean是否显示动画默认 true,脉冲效果
rowsNumber段落占位图行数控制骨架高度
loadingBoolean是否显示骨架屏控制显示/隐藏真实内容

插槽

插槽说明
default真实内容
template自定义骨架结构

variant 值

variant 值说明
p / text段落文本占位
h1 ~ h3标题占位
caption说明文字
button按钮占位
image图片占位
circle圆形占位(常用于头像)
rect矩形占位

4.9 Empty 空状态

参数类型说明注意事项
imageString图片地址自定义空状态图
image-sizeNumber图片大小(px)
descriptionString文字描述可插槽替代

插槽

插槽说明
default自定义描述文字
image自定义图片内容
extra额外操作区域

Empty - 代码示例:

<el-empty description="没有找到结果" image="https://.../empty.png">
  <template #extra>
    <el-button type="primary">搜索</el-button>
  </template>
</el-empty>

第五章:反馈与导航组件

5.1 Button 按钮

参数

参数类型说明注意事项
typeString类型(primary, success, warning, danger, info, text)控制按钮颜色
plainBoolean是否为朴素按钮背景色透明,边框同色
textBoolean是否为文字按钮无边框和背景色
linkBoolean是否为链接按钮类似 text,但有下划线
bgBoolean是否为带背景色的文字按钮仅 text 按钮有效
disabledBoolean是否禁用禁用状态不可点击
loadingBoolean是否加载中显示加载动画,禁用点击
iconString图标类名可与文字共存
native-typeString原生 type 属性(button, submit, reset)用于表单提交
autofocusBoolean是否自动聚焦
sizeString尺寸(large, default, small)影响按钮高度和字体

插槽

插槽说明
default按钮文本内容
loading自定义加载中内容

5.2 Dialog 对话框

参数

参数类型说明注意事项
v-model:visibleBoolean是否显示对话框必须绑定
titleString标题
widthString / Number宽度
topString顶部距离默认居中
modalBoolean是否显示遮罩层默认 true
append-to-bodyBoolean是否将 Dialog 挂载至 body避免层级问题
close-on-click-modalBoolean点击遮罩是否关闭默认 true
close-on-press-escapeBoolean按 Esc 是否关闭默认 true
show-closeBoolean是否显示关闭图标
draggableBoolean是否可拖拽仅支持带标题的对话框

事件

事件说明
open对话框打开时触发
opened打开动画结束时触发
close关闭时触发
closed关闭动画结束时触发

插槽

插槽说明
default对话框内容
title自定义标题
footer底部操作区

Dialog 基本结构 - 代码示例:

<el-dialog v-model:visible="dialogVisible" title="提示" width="50%">
  <span>对话框内容</span>
  <template #footer>
    <el-button @click="dialogVisible = false">取消</el-button>
    <el-button type="primary" @click="submit">确定</el-button>
  </template>
</el-dialog>

5.3 Message 消息提示(全局方法)

方法

方法语法说明
this.$messagethis.$message(options)显示消息
this.$message.successthis.$message.success(message)成功提示
this.$message.warningthis.$message.warning(message)警告提示
this.$message.infothis.$message.info(message)消息提示
this.$message.errorthis.$message.error(message)错误提示

Options 参数

参数类型说明
messageString消息内容
typeString类型(success, warning, info, error)
durationNumber显示时间(ms),0 表示不自动关闭
showCloseBoolean是否显示关闭按钮
centerBoolean文字是否居中
offsetNumber垂直偏移量(px)

注意:Message 是全局方法,无需模板调用,通常在 methods 中使用。

Message - 代码示例:

this.$message({ message: '操作成功', type: 'success' })
this.$message.success('提交成功')
this.$message.warning('请填写完整')
this.$message.info('系统提示')
this.$message.error('网络错误')

5.4 MessageBox 弹窗组件(Alert/Confirm)

方法

方法语法说明
this.$alertthis.$alert(message, title?, options?)警告弹窗
this.$confirmthis.$confirm(message, title?, options?)确认弹窗
this.$promptthis.$prompt(message, title?, options?)输入提示弹窗
this.$msgboxthis.$msgbox(options)通用弹窗

Options 常用参数

参数类型说明
confirmButtonTextString确认按钮文字
cancelButtonTextString取消按钮文字
typeString消息类型(success, warning, info, error)
inputTypeString输入框类型(text, password, textarea)
inputValidatorFunction输入验证函数
beforeCloseFunction关闭前回调

返回值

返回值说明
confirm用户点击确认
cancel用户点击取消或关闭
close通过 API 关闭

MessageBox Confirm - 代码示例:

this.$confirm('确定永久删除该文件?', '警告', {
  confirmButtonText: '删除',
  cancelButtonText: '取消',
  type: 'error'
}).then(() => {
  this.$message.success('删除成功');
}).catch(() => {
  this.$message.info('已取消');
});

5.5 Notification 通知

方法

方法语法说明
this.$notifythis.$notify(options)显示通知
this.$notify.successthis.$notify.success(options)成功通知
this.$notify.warningthis.$notify.warning(options)警告通知
this.$notify.infothis.$notify.info(options)消息通知
this.$notify.errorthis.$notify.error(options)错误通知

Options 参数

参数类型说明
titleString标题
messageString / VNode内容
typeString类型(success, warning, info, error)
durationNumber显示时间(ms),0 表示不自动关闭
positionString位置(top-right, top-left, bottom-right, bottom-left)
offsetNumber偏移量(px)
onCloseFunction关闭时回调
onClickFunction点击通知时触发

Notification - 代码示例:

this.$notify({
  title: '成功',
  message: '配置已保存',
  type: 'success',
  duration: 3000
});

5.6 Loading 加载指令与服务

使用方式

使用方式说明示例
指令形式用于 DOM 元素<div v-loading="loading">内容</div>
服务形式全局加载const loading = this.$loading(options)

Options 参数(服务)

参数类型说明
targetString / HTMLElement加载目标
bodyBoolean是否插入 body
fullscreenBoolean是否全屏
lockBoolean是否锁定滚动
textString显示文本
spinnerString自定义 spinner 类名
backgroundString遮罩背景色

方法

方法说明
loading.close()关闭加载

Loading 指令 - 代码示例:

<el-table v-loading="loading">
  <!-- 表格内容 -->
</el-table>

Loading 服务 - 代码示例:

const loading = this.$loading({ text: '加载中' });
setTimeout(() => { loading.close(); }, 2000);

5.7 Tooltip 文字提示

参数类型说明注意事项
contentString提示内容
effectString主题(dark, light)
placementString位置(top, bottom, left, right 等)支持 12 个方向
visible-arrowBoolean是否显示箭头
transitionString动画名称
disabledBoolean是否禁用
popper-classString自定义类名

插槽

插槽说明
default触发元素
content自定义提示内容

5.8 Popover 弹出框

参数类型说明注意事项
titleString标题
contentString内容
placementString位置同 Tooltip
triggerString触发方式(click, hover, focus, manual)默认 click
widthString / Number宽度
disabledBoolean是否禁用
popper-classString自定义类名

事件

事件说明
show弹出时触发
after-enter显示动画结束后触发
hide隐藏时触发
after-leave隐藏动画结束后触发

插槽

插槽说明
default触发元素
reference同 default

Popover - 代码示例:

<el-popover placement="right" trigger="click" :width="200">
  <template #reference>
    <el-button>点击弹出</el-button>
  </template>
  <span>弹出内容</span>
</el-popover>

5.9 Popconfirm 气泡确认框

参数类型说明注意事项
titleString确认框标题必填
confirmButtonTextString确认按钮文字
cancelButtonTextString取消按钮文字
confirmButtonTypeString确认按钮类型
cancelButtonTypeString取消按钮类型
iconString自定义图标
hide-iconBoolean是否隐藏图标

事件

事件说明
confirm点击确认按钮时触发
cancel点击取消按钮时触发

插槽

插槽说明
default触发元素
reference同 default

Popconfirm - 代码示例:

<el-popconfirm title="确定删除该记录?" @confirm="handleDelete">
  <template #reference>
    <el-button type="danger">删除</el-button>
  </template>
</el-popconfirm>

5.10 Dropdown 下拉菜单

组件

组件说明
<el-dropdown>下拉菜单容器
<el-dropdown-menu>菜单列表
<el-dropdown-item>菜单项

参数(el-dropdown)

参数类型说明
triggerString触发方式(hover, click, contextmenu)
sizeString尺寸(large, default, small)
split-buttonBoolean是否为分割按钮
hide-on-clickBoolean点击菜单项后是否隐藏
placementString菜单展开位置

事件

事件回调参数说明
command(command)点击菜单项时触发

插槽

插槽说明
default触发元素
dropdown下拉菜单

Dropdown - 代码示例:

<el-dropdown @command="handleCommand">
  <el-button type="primary">更多操作</el-button>
  <template #dropdown>
    <el-dropdown-menu>
      <el-dropdown-item command="edit">编辑</el-dropdown-item>
      <el-dropdown-item command="delete">删除</el-dropdown-item>
    </el-dropdown-menu>
  </template>
</el-dropdown>

5.11 Steps 步骤条

参数(el-steps)

参数类型说明注意事项
activeNumber当前步骤(从 0 开始)控制高亮
align-centerBoolean步骤居中对齐
directionString排列方向(horizontal, vertical)
spaceString / Number步骤间距不填则自适应

参数(el-step)

参数说明
title步骤标题
description描述文字
icon自定义图标
status状态(wait, process, finish, error, success)

插槽

插槽说明
default描述内容
title自定义标题
description自定义描述

5.12 Tabs 标签页

参数

参数类型说明注意事项
v-model:model-valueString绑定激活的标签页 name必须
typeString风格(card, border-card)
closableBoolean标签是否可关闭需监听 edit 事件
addableBoolean是否可添加
editableBoolean可增可删
stretchBoolean标签宽度自适应适合文本长度不一

事件

事件说明
tab-click标签被点击时触发
tab-change标签改变时触发
tab-remove标签被关闭时触发
tab-add点击新增标签时触发
edit新增或关闭时触发

插槽

插槽说明
default放置 el-tab-pane
label自定义标签标题

5.13 Breadcrumb 面包屑

组件

组件说明
<el-breadcrumb>面包屑容器
<el-breadcrumb-item>面包屑项

参数

参数类型说明
separatorString分隔符
separator-iconString分隔符图标

插槽

插槽说明
default放置 item
separator自定义分隔符

Breadcrumb - 代码示例:

<el-breadcrumb separator="/">
  <el-breadcrumb-item>首页</el-breadcrumb-item>
  <el-breadcrumb-item>用户管理</el-breadcrumb-item>
</el-breadcrumb>

5.14 PageHeader 页头

参数类型说明注意事项
titleString标题默认”返回”
contentString内容

事件

事件说明
back点击标题左侧区域时触发

插槽

插槽说明
default自定义内容
content同 default

PageHeader - 代码示例:

<el-page-header @back="goBack" title="返回" content="详情页面" />

第六章:布局与结构组件

6.1 Container 布局容器(el-container, el-header 等)

组件说明

组件说明使用场景
<el-container>外层容器,可嵌套 header/aside/main/footer页面根布局容器
<el-header>顶部布局放置导航栏、标题等
<el-aside>侧边栏布局放置菜单、工具栏
<el-main>主内容区放置表格、表单等核心内容
<el-footer>底部布局放置版权信息、页脚菜单

注意事项:

  • el-container 默认为 display: flex,子元素自动 flex 布局。
  • 可自由组合,如:header + main、header + aside + main、header + aside + main + footer。
  • el-container 作为根容器,建议设置 height: 100vh 实现全屏布局。

参数说明

参数类型说明代码示例
directionString子元素排列方向(horizontal, vertical)direction="vertical"
classString / Object / Array自定义类名class="layout-container"
styleObject / String内联样式:style="{ height: '100vh' }"

el-aside 特有参数:

  • width:侧边栏宽度,类型为 String,如 width="200px"(默认 300px)

6.2 Aside 侧边栏

  • 组件:<el-aside>
  • 作用:定义页面侧边栏区域,通常用于导航菜单。
  • 特点:
    • 可设置固定宽度。
    • 常与 el-menu 组件结合使用。
    • 支持折叠(需配合 JS 控制 width)。

示例:

<el-container>
  <el-aside width="200px">
    <el-menu>
      <el-menu-item index="1">首页</el-menu-item>
    </el-menu>
  </el-aside>
  <el-main>主内容</el-main>
</el-container>
  • 组件:<el-footer>
  • 作用:定义页面底部区域。
  • 特点:
    • 高度可自定义。
    • 通常放置版权信息、联系方式等。

示例:

<el-container>
  <el-header>头部</el-header>
  <el-main>内容</el-main>
  <el-footer style="text-align: center;">© 2025 公司名称</el-footer>
</el-container>

6.4 Header 页眉

  • 组件:<el-header>
  • 作用:定义页面顶部区域。
  • 特点:
    • 常用于放置 Logo、导航、用户信息。
    • 高度默认 60px,可通过 CSS 覆盖。

示例:

<el-header style="display: flex; align-items: center;">
  <h3>后台管理系统</h3>
  <div style="margin-left: auto;">用户:张三</div>
</el-header>

6.5 Main 主区域

  • 组件:<el-main>
  • 作用:定义页面主要内容区域。
  • 特点:
    • 自动填充剩余空间。
    • 可包含表格、表单、卡片等组件。

示例:

<el-main>
  <el-table :data="list">
    <!-- 表格内容 -->
  </el-table>
</el-main>

第七章:高级功能与主题定制

7.1 按需引入与自动导入

**目标:**减少打包体积,仅引入用到的组件。

方案一:自动按需引入(推荐)

Vite 配置示例:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  plugins: [
    vue(),
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
})

**优势:**无需手动导入组件和 API,自动完成。

7.2 国际化(i18n)配置

Element Plus 支持多语言。

步骤一:安装 vue-i18n

npm install vue-i18n@next

步骤二:配置语言包

import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
import ElementPlus from 'element-plus'
import zh from 'element-plus/es/locale/lang/zh-cn'
import en from 'element-plus/es/locale/lang/en'

const i18n = createI18n({
  locale: 'zh', // 默认语言
  messages: {
    zh: {
      ...zh,
      message: { hello: '你好' }
    },
    en: {
      ...en,
      message: { hello: 'Hello' }
    }
  }
})

const app = createApp()
app.use(ElementPlus, { locale: i18n.global.locale })
app.use(i18n)

步骤三:切换语言

i18n.global.locale.value = 'en'

7.3 主题定制(SCSS 变量覆盖)

通过覆盖 SCSS 变量实现主题定制。

步骤一:创建 SCSS 文件(如 styles/element-variables.scss

// 自定义主题变量
$--color-primary: #409eff;
$--color-success: #67c23a;
$--color-warning: #e6a23c;
$--color-danger: #f56c6c;
$--color-info: #909399;

// 引入 Element Plus 默认样式(必须在变量之后)
@use "element-plus/theme-chalk/src/index.scss" as *;

步骤二:在 vite.config.js 中配置

css: {
  preprocessorOptions: {
    scss: {
      additionalData: `@use "@/styles/element-variables.scss" as *;`
    }
  }
}

注意:确保项目使用 SCSS,并正确配置路径别名。

7.4 图标使用(@element-plus/icons-vue)

Element Plus 图标需单独安装。

安装:

npm install @element-plus/icons-vue

使用方式一:全局注册(推荐)

import { createApp } from 'vue'
import * as Icons from '@element-plus/icons-vue'

const app = createApp(App)
// 注册所有图标
Object.keys(Icons).forEach(key => {
  app.component(key, Icons[key])
})

使用方式二:局部使用

<script setup>
import { Search, Edit } from '@element-plus/icons-vue'
</script>
<template>
  <el-button :icon="Search">搜索</el-button>
  <el-icon><Edit /></el-icon>
</template>

**图标命名规则:**PascalCase,如 UserFilled, ArrowDown

7.5 TypeScript 支持说明

Element Plus 完全使用 TypeScript 编写,提供完整类型定义。

优势:

  • 组件属性、事件、插槽均有类型提示。
  • 支持 defineComponentref 类型推断。
  • 与 Volar 插件配合,实现模板内类型检查。

建议配置:

// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2018",
    "module": "ESNext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "types": ["element-plus/global"]
  }
}

提示:使用 Volar 替代 Vetur 以获得更好的 TS 支持。

第八章:实战项目整合

8.1 搭建后台管理系统基础布局

使用 el-container 系列组件搭建经典 侧边栏 + 页头 + 主内容区 布局。

<!-- App.vue -->
<template>
  <el-container style="height: 100vh;">
    <!-- 侧边栏 -->
    <el-aside width="200px" style="background-color: #545c64;">
      <el-menu
        :default-active="$route.path"
        background-color="#545c64"
        text-color="#fff"
        active-text-color="#ffd04b"
        router
      >
        <el-menu-item index="/dashboard">
          <el-icon><HomeFilled /></el-icon>
          <span>首页</span>
        </el-menu-item>
        <el-menu-item index="/users">
          <el-icon><User /></el-icon>
          <span>用户管理</span>
        </el-menu-item>
      </el-menu>
    </el-aside>

    <el-container>
      <!-- 页头 -->
      <el-header style="background-color: #fff; box-shadow: 0 1px 4px rgba(0,21,41,.08);">
        <div style="display: flex; align-items: center; height: 100%;">
          <h3 style="margin: 0;">后台管理系统</h3>
          <div style="margin-left: auto;">
            <el-dropdown @command="handleCommand">
              <span>管理员 <el-icon><ArrowDown /></el-icon></span>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item command="logout">退出登录</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </div>
        </div>
      </el-header>

      <!-- 主内容区 -->
      <el-main>
        <router-view />
      </el-main>
    </el-container>
  </el-container>
</template>

<script setup>
import { HomeFilled, User, ArrowDown } from '@element-plus/icons-vue'

const handleCommand = (command) => {
  if (command === 'logout') {
    // 退出逻辑
    console.log('退出登录')
  }
}
</script>

说明:

  • router 属性启用 Vue Router 模式,index 为路由路径。
  • default-active="$route.path" 高亮当前路由菜单项。

8.2 使用 ElMenu 实现侧边栏导航

功能增强:支持多级菜单

<el-menu :default-active="$route.path" router>
  <el-sub-menu index="1">
    <template #title>
      <el-icon><Setting /></el-icon>
      <span>系统管理</span>
    </template>
    <el-menu-item index="/users">用户管理</el-menu-item>
    <el-menu-item index="/roles">角色管理</el-menu-item>
  </el-sub-menu>
</el-menu>

动态菜单(从 API 获取)

const menuData = ref([
  {
    id: 1,
    title: '用户管理',
    path: '/users',
    icon: 'User'
  },
  {
    id: 2,
    title: '订单管理',
    path: '/orders',
    icon: 'Tickets'
  }
])

渲染动态菜单:

<el-menu-item
  v-for="item in menuData"
  :key="item.id"
  :index="item.path"
>
  <el-icon><component :is="item.icon" /></el-icon>
  <template #title>{{ item.title }}</template>
</el-menu-item>

注意:需提前注册图标组件或使用 component :is 动态渲染。

8.3 表格 + 分页 + 搜索表单联动

实现用户列表页的搜索、分页、刷新联动。

<template>
  <div>
    <!-- 搜索表单 -->
    <el-form :inline="true" :model="searchForm" class="demo-form-inline">
      <el-form-item label="用户名">
        <el-input v-model="searchForm.username" placeholder="用户名" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="fetchData">查询</el-button>
        <el-button @click="resetSearch">重置</el-button>
      </el-form-item>
    </el-form>

    <!-- 表格 -->
    <el-table :data="tableData" border style="width: 100%">
      <el-table-column prop="id" label="ID" width="80" />
      <el-table-column prop="username" label="用户名" />
      <el-table-column prop="email" label="邮箱" />
      <el-table-column label="操作" width="150">
        <template #default="scope">
          <el-button size="small" @click="editUser(scope.row)">编辑</el-button>
          <el-button size="small" type="danger" @click="deleteUser(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <el-pagination
      v-model:current-page="currentPage"
      v-model:page-size="pageSize"
      :total="total"
      layout="total, sizes, prev, pager, next, jumper"
      @size-change="fetchData"
      @current-change="fetchData"
      style="margin-top: 20px; justify-content: flex-end;"
    />
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const searchForm = ref({ username: '' })
const tableData = ref([])
const total = ref(0)
const currentPage = ref(1)
const pageSize = ref(10)

// 模拟 API 请求
const fetchData = async () => {
  // 实际项目中调用 API
  console.log('请求参数:', {
    page: currentPage.value,
    limit: pageSize.value,
    username: searchForm.value.username
  })
  // 模拟数据
  tableData.value = Array.from({ length: pageSize.value }, (_, i) => ({
    id: (currentPage.value - 1) * pageSize.value + i + 1,
    username: `user${(currentPage.value - 1) * pageSize.value + i + 1}`,
    email: `user${(currentPage.value - 1) * pageSize.value + i + 1}@example.com`
  }))
  total.value = 100 // 模拟总数
}

const resetSearch = () => {
  searchForm.value.username = ''
  currentPage.value = 1
  fetchData()
}

onMounted(() => {
  fetchData()
})
</script>

8.4 表单提交与验证完整流程

使用 el-form 实现用户添加表单,包含验证。

<template>
  <el-form
    :model="form"
    :rules="rules"
    ref="formRef"
    label-width="80px"
  >
    <el-form-item label="用户名" prop="username">
      <el-input v-model="form.username" />
    </el-form-item>
    <el-form-item label="邮箱" prop="email">
      <el-input v-model="form.email" />
    </el-form-item>
    <el-form-item label="角色" prop="role">
      <el-select v-model="form.role" placeholder="请选择角色">
        <el-option label="管理员" value="admin" />
        <el-option label="普通用户" value="user" />
      </el-select>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="submitForm">提交</el-button>
      <el-button @click="resetForm">重置</el-button>
    </el-form-item>
  </el-form>
</template>

<script setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'

const form = ref({
  username: '',
  email: '',
  role: ''
})

const rules = {
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 3, max: 15, message: '长度在 3 到 15 个字符', trigger: 'blur' }
  ],
  email: [
    { required: true, message: '请输入邮箱地址', trigger: 'blur' },
    { type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
  ],
  role: [
    { required: true, message: '请选择角色', trigger: 'change' }
  ]
}

const formRef = ref(null)

const submitForm = () => {
  formRef.value.validate((valid) => {
    if (valid) {
      console.log('提交数据:', form.value)
      // 调用 API 提交
      ElMessage.success('添加成功')
    } else {
      ElMessage.error('请检查表单')
      return false
    }
  })
}

const resetForm = () => {
  formRef.value.resetFields()
}
</script>

8.5 使用 Dialog 实现增删改查弹窗

编辑用户弹窗

<el-dialog v-model="dialogVisible" :title="isEdit ? '编辑用户' : '添加用户'" width="500px">
  <el-form :model="form" :rules="rules" ref="formRef" label-width="80px">
    <el-form-item label="用户名" prop="username">
      <el-input v-model="form.username" />
    </el-form-item>
    <el-form-item label="邮箱" prop="email">
      <el-input v-model="form.email" />
    </el-form-item>
  </el-form>

  <template #footer>
    <el-button @click="dialogVisible = false">取消</el-button>
    <el-button type="primary" @click="submitForm">确定</el-button>
  </template>
</el-dialog>
<script setup>
const dialogVisible = ref(false)
const isEdit = ref(false)
const form = ref({})

const openDialog = (row = null) => {
  if (row) {
    isEdit.value = true
    form.value = { ...row }
  } else {
    isEdit.value = false
    form.value = { username: '', email: '' }
  }
  dialogVisible.value = true
}

const submitForm = () => {
  // 提交逻辑
  dialogVisible.value = false
  fetchData() // 刷新列表
}
</script>

删除确认

const deleteUser = (row) => {
  ElMessageBox.confirm(`确定删除用户 ${row.username}?`, '警告', {
    type: 'error',
    confirmButtonText: '删除',
    cancelButtonText: '取消'
  }).then(() => {
    // 调用删除 API
    ElMessage.success('删除成功')
    fetchData()
  }).catch(() => {
    ElMessage.info('已取消')
  })
}

8.6 权限控制与组件显示策略

方案一:指令控制(v-permission)

// directives/permission.js
const permission = {
  mounted(el, binding) {
    const { value } = binding
    const permissions = ['admin', 'editor'] // 从 store 获取用户权限
    if (value && !permissions.includes(value)) {
      el.style.display = 'none'
    }
  }
}

export default permission

使用:

<el-button v-permission="'admin'">管理员专属</el-button>

方案二:组件封装

<template>
  <el-button v-if="hasPermission('edit')" @click="edit">编辑</el-button>
</template>

<script setup>
const userRole = ref('user') // 从 store 获取

const hasPermission = (action) => {
  const permissions = {
    admin: ['view', 'edit', 'delete'],
    user: ['view']
  }
  return permissions[userRole.value]?.includes(action)
}
</script>

路由级权限

router.beforeEach 中判断用户角色,动态加载路由或跳转 403。