封面来源:本文封面来源于 Element UI 官网,如有侵权,请联系删除。
参考视频:适合后端编程人员的 ElementUI教程,结合SpringBoot项目案例,已完结!!!
1. Element UI 的引言
The world’s most popular Vue UI framework
Element UI 是一个 Vue UI 框架,因此在学习的时候需要有一定的 Vue 基础(包括 Vue 脚手架),相关文章可在本站搜索【Vue2.0 快速入门】一文进行阅读。
Element UI 官网:Element UI
Element UI 国内官网站点:Element UI zh
根据官网得知:Element UI 是一个 网站快速成型工具,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的 桌面端组件库。
现在 Element UI 已经支持 Vue 3.0 了,但 在本文我们依旧使用 Vue 2.0 与 Element UI 进行讲解。
本文 只做 常用组件与 思路的讲解,详细内容可以参考官方文档。
对 Element UI 下一个定义:Element UI 就是一个基于 Vue 的 UI 框架,它基于 Vue 开发了很多相关组件,方便我们快速开发页面。
Element UI 的由来
Element UI 是 饿了么前端团队 基于 Vue 进行开发并开源的框架,Element UI 中提供的全部都是封装好的组件。
2. 快速开始
2.1 基本安装
安装方式
在 官方文档 中,提供了两种安装方式,一种是基于 Vue 脚手架的,一种是基于 CDN 加速的:
NPM:
npm i element-ui -S
CDN:
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
在如今的环境下,我们的项目都是前后端分离的,因此不再选用 CDN 的方式进行安装,选择 NPM 的方式进行安装。
安装步骤
那么我们就需要先通过 Vue 脚手架创建一个名为 element 的项目:
vue init webpack element
等待项目创建完毕后,前往项目根目录执行以下命令,来启动一下创建的项目:
npm start
如果可以启动成功,证明我们的创建没有问题。
然后在项目的根目录中执行以下命令,安装 Element UI:
npm i element-ui -S
等待安装完毕后,指定当前项目中使用 Element UI。前往项目的 src 目录下,找到 main.js 文件,在这个文件中添加以下代码:
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 在 Vue 脚手架中使用 Element UI
Vue.use(ElementUI);
到此,Element UI 就安装成功了!
2.2 第一个 Demo
初探按钮组件:
<template>
<div>
<!-- 使用默认按钮组件 -->
<el-row>
<el-button>默认按钮</el-button>
<el-button type="primary">主要按钮</el-button>
<el-button type="success">成功按钮</el-button>
<el-button type="info">信息按钮</el-button>
<el-button type="warning">警告按钮</el-button>
<el-button type="danger">危险按钮</el-button>
</el-row>
<br>
<!-- 使用简洁按钮 -->
<el-row>
<el-button plain>朴素按钮</el-button>
<el-button type="primary" plain>主要按钮</el-button>
<el-button type="success" plain>成功按钮</el-button>
<el-button type="info" plain>信息按钮</el-button>
<el-button type="warning" plain>警告按钮</el-button>
<el-button type="danger" plain>危险按钮</el-button>
</el-row>
<br>
<!-- 使用圆角按钮 -->
<el-row>
<el-button round>圆角按钮</el-button>
<el-button type="primary" round>主要按钮</el-button>
<el-button type="success" round>成功按钮</el-button>
<el-button type="info" round>信息按钮</el-button>
<el-button type="warning" round>警告按钮</el-button>
<el-button type="danger" round>危险按钮</el-button>
</el-row>
<br>
<!-- 使用图标按钮 -->
<el-row>
<el-button icon="el-icon-search" circle></el-button>
<el-button type="primary" icon="el-icon-edit" circle></el-button>
<el-button type="success" icon="el-icon-check" circle></el-button>
<el-button type="info" icon="el-icon-message" circle></el-button>
<el-button type="warning" icon="el-icon-star-off" circle></el-button>
<el-button type="danger" icon="el-icon-delete" circle></el-button>
</el-row>
</div>
</template>
3. 基本组件的使用
总结: 日后使用 Element UI 的相关组件时,所有组件都是通过 el-组件名称 进行使用!
3.1 Button 按钮
创建按钮
<el-button>默认按钮</el-button>
按钮属性的使用
<el-button type="primary" size="mini" :plain="true" round>primary</el-button>
<el-button type="success" size="small" :plain="true" round>success</el-button>
<el-button type="warning" size="medium" :plain="true" round>warning</el-button>
<el-button type="danger " size="medium" icon="el-icon-delete" circle></el-button>
总结: 在 Element UI 中组件属性的使用都是直接按照 属性名=属性值 的方式写在对应的组件标签上!
在 Element UI 中:
1、如果一个属性的类型是 boolean 且默认值是 false,那么可以直接在标签上使用这个属性,而不指定值,这时候的值是 true。
2、如果一个属性的类型是 boolean,且默认值是 true,如果想要指定它的值为 false,那么需要使用 Vue 的绑定语法,即: :属性名="false"。

按钮有很多属性,具体参考 Button Attributes
按钮组与图标按钮
<el-button-group>
<el-button type="primary" icon="el-icon-arrow-left">上一页</el-button>
<el-button type="primary">下一页<i class="el-icon-arrow-right el-icon--right"></i></el-button>
</el-button-group>

3.2 Link 文字链接
创建文字链接
<el-link href="https://mofan212.github.io" target="_blank">默认链接</el-link>
文字链接属性的使用
<el-link type="primary" :underline="false">主要链接</el-link>
<el-link type="success">成功链接</el-link>
<el-link type="warning" disabled>警告链接</el-link>
<el-link type="danger">危险链接</el-link>
<el-link type="info" icon="el-icon-platform-eleme">信息链接</el-link>

Link 文字链接的属性,具体参考 Link Attributes
3.3 Layout (栅格)布局
在官网的 Layout 布局 上有这样一句话:通过基础的 24 分栏,迅速简便地创建布局。
就是说: 在 Element UI 中的布局组件将页面划分为多个行 row,每行最多分为 24 栏(列)。
使用 Layout 组件
<template>
<div>
<h1>Layout布局组件的使用</h1>
<el-row>
<el-col :span="24"><div class="grid-content bg-purple-dark"></div></el-col>
</el-row>
<br>
<el-row>
<el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
<el-col :span="6"><div class="grid-content bg-purple-light"></div></el-col>
<el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
<el-col :span="6"><div class="grid-content bg-purple-light"></div></el-col>
</el-row>
</div>
</template>
<style>
.bg-purple-dark {
background: #99a9bf;
}
.grid-content {
border-radius: 4px;
min-height: 36px;
}
.bg-purple {
background: #d3dce6;
}
.bg-purple-light {
background: #e5e9f2;
}
</style>

注意:
1、在一个布局组件中,是由 row 和 col 组合而成的。
2、在使用时需要区分 row 的属性和 col 的属性。
行属性的使用
<el-row :gutter="50" tag="span">
<el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
<el-col :span="6"><div class="grid-content bg-purple-light"></div></el-col>
<el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
<el-col :span="6"><div class="grid-content bg-purple-light"></div></el-col>
</el-row>

基本上常用的也就 gutter 和 tag 两个属性,其他属性可参考:Row Attributes
列属性的使用
<h1>Layout组件中使用偏移</h1>
<el-row>
<el-col :span="12" :offset="6"><div class="grid-content bg-purple"></div></el-col>
</el-row>
<br>
<el-row>
<el-col :span="12" :offset="6"><div class="grid-content bg-purple"></div></el-col>
<el-col :span="12" :offset="6"><div class="grid-content bg-purple-light"></div></el-col>
</el-row>
<br>
<el-row>
<el-col :span="12" :offset="6" :push="3"><div class="grid-content bg-purple"></div></el-col>
<el-col :span="6"><div class="grid-content bg-purple-light"></div></el-col>
</el-row>

注意 span 和 offset 属性的区别!
其他属性可参考:Col Attributes
3.4 Container 布局容器
官网的说明
官网链接:Container 布局容器
用于布局的容器组件,方便快速搭建页面的基本结构:
<el-container>:外层容器。当子元素中包含 <el-header> 或 <el-footer> 时,全部子元素会垂直上下排列,否则会水平左右排列。
<el-header>:顶栏容器。
<el-aside>:侧边栏容器。
<el-main>:主要区域容器。
<el-footer>:底栏容器。
注意: 以上组件采用了 flex 布局,使用前请确定目标浏览器是否兼容。此外,<el-container> 的子元素只能是后四者,后四者的父元素也只能是 <el-container>。
容器的基本使用
<template>
<div>
<h1>布局容器的使用</h1>
<!-- 创建容器 -->
<el-container>
<!-- header -->
<el-header><div><span>我是标题</span></div></el-header>
<!-- 容器的嵌套使用 -->
<el-container>
<!-- aside -->
<el-aside><div><span>我是菜单</span></div></el-aside>
<!-- main -->
<el-main><div><span>我是中心内容</span></div></el-main>
</el-container>
<el-footer><div><span>我是页脚</span></div></el-footer>
</el-container>
</div>
</template>
<style>
.el-header, .el-footer {
background-color: #B3C0D1;
color: #333;
text-align: center;
line-height: 60px;
}
.el-aside {
background-color: #D3DCE6;
color: #333;
text-align: center;
line-height: 200px;
}
.el-main {
background-color: #E9EEF3;
color: #333;
text-align: center;
line-height: 160px;
}
body > .el-container {
margin-bottom: 40px;
}
.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
line-height: 260px;
}
.el-container:nth-child(7) .el-aside {
line-height: 320px;
}
</style>

水平容器与垂直容器
<el-container> 有只有一个属性:
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| direction | 子元素的排列方向 | string | horizontal / vertical | 子元素中有 el-header 或 el-footer 时为 vertical,否则为 horizontal |
<!-- 创建容器 -->
<el-container direction="horizontal">
<!-- header -->
<el-header><div><span>我是标题</span></div></el-header>
<el-container direction="vertical">
<!-- aside -->
<el-aside><div><span>我是菜单</span></div></el-aside>
<!-- main -->
<el-main><div><span>我是中心内容</span></div></el-main>
</el-container>
<el-footer><div><span>我是页脚</span></div></el-footer>
</el-container>

容器其他属性的使用
Header Attributes:
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| height | 顶栏高度 | string | — | 60px |
Aside Attributes:
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| width | 侧边栏宽度 | string | — | 300px |
Footer Attributes:
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| height | 底栏高度 | string | — | 60px |
代码示例:
<h1>容器其他属性的使用</h1>
<!-- 创建容器 -->
<el-container>
<!-- header -->
<el-header height="80px"><div><h1>我是标题</h1></div></el-header>
<el-container>
<!-- aside -->
<el-aside width="200px"><div><h1>我是菜单</h1></div></el-aside>
<!-- main -->
<el-main><div><h1>我是中心内容</h1></div></el-main>
</el-container>
<el-footer height="100px"><div><h1>我是页脚</h1></div></el-footer>
</el-container>

4. 表单组件的使用
4.1 Radio 单选按钮
创建 Radio 单选按钮
<template>
<div>
<h1>Radio的使用</h1>
<el-radio v-model="label" label="男">男</el-radio>
<el-radio v-model="label" label="女">女</el-radio>
</div>
</template>
<script>
export default {
name: 'Radio',
data() {
return {
label: '男'
}
}
}
</script>

要使用 Radio 组件,只需要设置 v-model 绑定变量,选中意味着变量的值为相应 Radio label 属性的值,label 可以是 String、Number 或 Boolean。
注意: 在使用 Radio 单选按钮的时候,至少要加入 v-model 和 label 两个属性。
Radio 按钮属性的使用
<h1>Radio按钮属性的使用</h1>
<el-radio v-model="radio" label="1" name="radio" size="mini" border>备选项1</el-radio>
<el-radio v-model="radio" label="2" name="radio" size="small" disabled border>备选项2</el-radio>
<el-radio v-model="radio" label="3" name="radio" size="mudium" border>备选项3</el-radio>
<script>
export default {
name: 'Radio',
data() {
return {
radio: '1'
}
}
}
</script>

name 属性就是原生的 name 属性,用于向后端传递值时使用。
size 属性表示 Radio 的尺寸,仅在 border 属性为 true 时有效,其值只有三种可选。
属性的使用还是按照 属性名=属性值 的方式直接卸载对应的组件标签上。
Radio 属性具体的使用参考:Radio Attributes
Radio 事件的使用
<h1>Radio绑定事件的使用</h1>
<el-radio v-model="event" label="1" @change="changeValue">选项1</el-radio>
<el-radio v-model="event" label="2" @change="changeValue">选项2</el-radio>
<script>
export default {
name: 'Radio',
data() {
return {
event: '1'
}
},
methods: {
changeValue() {
alert("事件触发 ==>" + this.event);
}
}
}
</script>

总结:
1、事件的使用也是和属性的使用是一样的,都是直接写在对应的组件标签上。
2、事件在使用时必须使用 Vue 中绑定事件的方式进行使用,如:@事件名=事件处理函数(绑定在 Vue 组件中对应函数)
Radio 按钮组
<h1>单选按钮组</h1>
<el-radio-group v-model="radio" >
<el-radio label="3" border>备选项3</el-radio>
<el-radio label="6" border>备选项6</el-radio>
<el-radio label="9" border>备选项9</el-radio>
</el-radio-group>
<script>
export default {
name: 'Radio',
data() {
return {
radio: '3',
}
},
}
</script>
使用 Radio 按钮组,只需要绑定一次数据,而无需每次都绑定。
按钮组也有自己的属性,具体可以查看:Radio-group Attributes
同样,按钮组也有自己的事件,和单个 Radio 类似,就不在此赘述了,可以参考:Radio-group Events
只需要把 el-radio 元素换成 el-radio-button 元素就可以实现按钮样式的单选组合。其属性可以参考:Radio-button Attributes

4.2 Checkbox 多选框
多选框的基本使用
<template>
<div>
<h1>Checkbox组件的使用</h1>
<el-checkbox v-model="checked" true-label="北京">北京</el-checkbox>
<el-checkbox v-model="checked" true-label="上海">上海</el-checkbox>
<el-checkbox v-model="checked" true-label="广州">广州</el-checkbox>
<el-checkbox border checked true-label="杭州">杭州</el-checkbox>
</div>
</template>
<script>
export default {
name: 'Checkbox',
data() {
return{
checked: "北京"
}
}
};
</script>

与 Radio 单选按钮一样,Checkbox 也有自己的属性,两者都差不多,具体可以参考:Checkbox Attributes
同样的,Checkbox 也有属于自己的事件,其事件也是当绑定值变化时触发的事件,事件名称为 change,其回调参数是更新后的值。
多选框组的使用
上述案例中,Checkbox 似乎与单选按钮一样,根本无法实现多选,那是因为要使用多选框组才能实现多选。
多选框组适用于多个勾选框绑定到同一个数组的情景,通过是否勾选来表示这一组选项中选中的项。
checkbox-group 元素能把多个 Checkbox 管理为一组,只需要在 Group 中使用 v-model 绑定 Array 类型的变量即可。 el-checkbox 的 label 属性是该 Checkbox 对应的值,若该标签中无内容,则该属性也充当 Checkbox 按钮后的介绍。label 与数组中的元素值相对应,如果存在指定的值则为选中状态,否则为不选中。
<el-checkbox-group v-model="checkList" min="1">
<el-checkbox label="复选框 A"></el-checkbox>
<el-checkbox label="复选框 B"></el-checkbox>
<el-checkbox label="复选框 C"></el-checkbox>
<el-checkbox label="禁用" disabled></el-checkbox>
<el-checkbox label="选中且禁用" disabled></el-checkbox>
</el-checkbox-group>
<script>
export default {
name: 'Checkbox',
data() {
return{
checkList: ['选中且禁用','复选框 A']
}
}
};
</script>

多选框组也有自己的属性,可以指定被勾选的 Checkbox 的最大 / 小数量,具体可以参考:Checkbox-group Attributes
多选框组也有属于自己的事件,和单个 Checkbox 一样,其事件也是当绑定值变化时触发的事件,事件名称为 change,其回调参数是更新后的值。
除此之外,还有 Checkbox-Button 可以使用,就和 Radio-Button 一样,具体可以参考:按钮样式 和 Checkbox-button Attributes
4.3 Input 输入框
注意:
1、Input 为受控组件,它 总会显示 Vue 绑定值。
2、通常情况下,应当处理 input 事件,并更新组件的绑定值(或使用 v-model)。否则,输入框内显示的值将不会改变。
3、Input 不支持 v-model 修饰符。
创建 Input 输入框
<template>
<div>
<h1>Input组件的使用</h1>
<el-input placeholder="请输入内容" v-model="name"></el-input>
</div>
</template>
<script>
export default {
name: 'Input',
data() {
return {
name: 'mofan'
}
}
}
</script>

Input 的常用属性
Input 的属性有很多,完整属性列表可参考 Input Attributes,常用属性如下表所示:
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| type | 类型 | string | text,textarea 和其他原生 input 的 type 值 | text |
| value / v-model | 绑定值 | string / number | — | — |
| maxlength | 原生属性,最大输入长度 | number | — | — |
| minlength | 原生属性,最小输入长度 | number | — | — |
| show-word-limit | 是否显示输入字数统计,只在 type = "text" 或 type = "textarea" 时有效 | boolean | — | false |
| placeholder | 输入框占位文本 | string | — | — |
| clearable | 是否可清空 | boolean | — | false |
| show-password | 是否显示切换密码图标 | boolean | — | false |
| disabled | 禁用 | boolean | — | false |
| size | 输入框尺寸,只在 type!="textarea" 时有效 | string | medium / small / mini | — |
| prefix-icon | 输入框头部图标 | string | — | — |
| suffix-icon | 输入框尾部图标 | string | — | — |
| rows | 输入框行数,只对 type="textarea" 有效 | number | — | 2 |
| autosize | 自适应内容高度,只对 type="textarea" 有效,可传入对象,如,{ minRows: 2, maxRows: 6 } | boolean / object | — | false |
| autocomplete | 原生属性,自动补全 | string | on, off | off |
| name | 原生属性 | string | — | — |
| readonly | 原生属性,是否只读 | boolean | — | false |
| max | 原生属性,设置最大值 | — | — | — |
| min | 原生属性,设置最小值 | — | — | — |
| form | 原生属性 | string | — | — |
| label | 输入框关联的 label 文字 | string | — | — |
注意: 要想 Input 输入框能够键入值,<el-Input> 必须有 v-model 属性!
Input 事件的使用
根据 Element UI 的官网,Input 输入框有以下事件:
| 事件名称 | 说明 | 回调参数 |
|---|---|---|
| blur | 在 Input 失去焦点时触发 | (event: Event) |
| focus | 在 Input 获得焦点时触发 | (event: Event) |
| change | 仅在输入框失去焦点或用户按下回车时触发 | (value: string | number) |
| input | 在 Input 值改变时触发 | (value: string | number) |
| clear | 在点击由 clearable 属性生成的清空按钮时触发 | — |
对于 change 事件来说,当我们在输入框内输入一次数据后,当输入框失去焦点或按下回车就会触发该事件。如果输入框内的数据没有发生改变,那么就算输入框再失去焦点或者再按下回车都 不出 触发该该事件,直到输入框内的数据发生改变。
<h1>Input事件的使用</h1>
<el-input v-model="username" @blur="aaa" @focus="bbb"></el-input>
<br>
<br>
<el-input v-model="change" @input="ccc" placeholder="input事件的使用"></el-input>
<script>
export default {
name: 'Input',
data() {
return {
username: '',
change: '',
}
},
methods: {
aaa() {
console.log("失去焦点");
},
bbb() {
console.log("获得焦点");
},
ccc(value) {
console.log("输入框内的值: " + value);
}
}
}
</script>
注意: 当我们使用组件的事件并指定触发事件后执行的方法时,在组件上只需要书写方法名即可,不要书写括号或者参数。比如下面这种书写方式是错误的:
<el-input v-model="change" @input="ccc()" placeholder="input事件的使用"></el-input>
下面这种也是错误的:
<el-input v-model="change" @input="ccc(value)" placeholder="input事件的使用"></el-input>
Input 方法的使用
跟着官方文档继续走,会发现 Input 组件还有名为 Input Methods 的东西,那这是啥?
需要明白的是, 在 Element UI 中所有组件都存在属性、事件和方法:
(Attributes)属性是用来定义组件初始的状态。直接写在对应的组件标签上,按照属性名=属性值的方式进行使用(Events)事件是在组件发生某种状态变化时,触发组件特定的事件。直接使用 Vue 绑定事件方式写在对应组件标签上,按照@事件名=Vue中事件处理函数名的方式进行使用(Methods)方法是用来改变组件的默认状态。使用时需要先在对应组件标签上使用ref=组件别名,然后通过this.$refs.组件别名.方法名()的方式进行调用
对于 Input 输入框来说,官方提供了一下几种方法:
| 方法名 | 说明 | 参数 |
|---|---|---|
| focus | 使 input 获取焦点 | — |
| blur | 使 input 失去焦点 | — |
| select | 选中 input 中的文字 | — |
<h1>Input方法的使用</h1>
<el-input v-model="method" ref="input"></el-input>
<br>
<br>
<el-button @click="focusInputs">focus</el-button>
<el-button @click="blurInputs">blur</el-button>
<script>
export default {
name: 'Input',
data() {
return {
method: ''
}
},
methods: {
// 调用focus方法
focusInputs() {
this.$refs.input.focus();
},
// 调用blur方法
blurInputs() {
this.$refs.input.blur();
}
}
}
</script>

总结:
1、当我们使用组件的方法时,需要在对应的组件上加入 ref=组件别名,这样就会将当前组件绑定给 Vue 实例
2、在调用组件方法(Methods)时,可以直接使用 this.$refs.组件别名.组件方法名(); 的形式调用组件方法。
4.4 Select 选择器
当选项过多时,使用下拉菜单展示并选择内容。
创建 Select 选择器
<template>
<div>
<h1>Select选择器的使用</h1>
<!-- 数据写死在页面上 -->
<el-select v-model="language" placeholder="请选择语言">
<el-option value="Java">Java</el-option>
<el-option value="C">C</el-option>
<el-option value="C++">C++</el-option>
</el-select>
<!-- 动态地获取数据 -->
<el-select v-model="dept" placeholder="请选择部门">
<el-option
v-for="option in options"
:label="option.name"
:value="option.id"
:key="option.id"
></el-option>
</el-select>
</div>
</template>
<script>
export default {
name: "Select",
data() {
return {
options: [
{ id: "1", name: "研发" },
{ id: "2", name: "中台" },
{ id: "3", name: "财务" },
{ id: "4", name: "人事" },
],
dept: '',
language: '',
};
},
};
</script>

注意: 在下拉列表中,<el-option> 必须存在 value 属性值;在 <el-select> 必须存在 v-model 属性以进行数据绑定。
如果我们需要从数据库中获取数据,那么只需要在 Vue 生命周期的 created 中通过 Axios 获取数据即可。后续会有案例讲解,别慌。 😎
Select 的常用属性
如果 Select 的绑定值为对象类型,请务必指定 value-key 作为它的唯一性标识。
Input 的属性有很多,完整属性列表可参考 Select Attributes,常用属性如下表所示:
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| value / v-model | 绑定值 | boolean / string / number | — | — |
| multiple | 是否多选 | boolean | — | false |
| disabled | 是否禁用 | boolean | — | false |
| value-key | 作为 value 唯一标识的键名,绑定值为对象类型时必填 | string | — | value |
| size | 输入框尺寸 | string | medium/small/mini | — |
| clearable | 是否可以清空选项 | boolean | — | false |
| collapse-tags | 多选时是否将选中值按文字的形式展示 | boolean | — | false |
| multiple-limit | 多选时用户最多可以选择的项目数,为 0 则不限制 | number | — | 0 |
| name | select input 的 name 属性 | string | — | — |
| placeholder | 占位符 | string | — | 请选择 |
| filterable | 是否可搜索 | boolean | — | false |
| no-match-text | 搜索条件无匹配时显示的文字,也可以使用 slot="empty" 设置 | string | — | 无匹配数据 |
| no-data-text | 选项为空时显示的文字,也可以使用 slot="empty" 设置 | string | — | 无数据 |
| popper-class | Select 下拉框的类名 | string | — | — |
Select 事件的使用
对于 Select 选择器来说,Element UI 提供了以下几种事件:
| 事件名称 | 说明 | 回调参数 |
|---|---|---|
| change | 选中值发生变化时触发 | 目前的选中值 |
| visible-change | 下拉框出现/隐藏时触发 | 出现则为 true,隐藏则为 false |
| remove-tag | 多选模式下移除 tag 时触发 | 移除的 tag 值 |
| clear | 可清空的单选模式下用户点击清空按钮时触发 | — |
| blur | 当 input 失去焦点时触发 | (event: Event) |
| focus | 当 input 获得焦点时触发 | (event: Event) |
<el-select v-model="dept" multiple placeholder="请选择部门" @change="aaa">
<el-option
v-for="option in options"
:label="option.name"
:value="option.id"
:key="option.id"
></el-option>
</el-select>
<script>
export default {
name: "Select",
data() {
return {
options: [
{ id: "1", name: "研发" },
{ id: "2", name: "中台" },
{ id: "3", name: "财务" },
{ id: "4", name: "人事" },
],
dept: '',
};
},
methods: {
aaa(value) {
console.log(value);
}
}
};
</script>
Select 方法的使用
Select 选择器也有自己的方法,它有以下两个方法:
| 方法名 | 说明 | 参数 |
|---|---|---|
| focus | 使 input 获取焦点 | - |
| blur | 使 input 失去焦点,并隐藏下拉框 | - |
4.5 Switch 开关
表示两种相互对立的状态间的切换,多用于触发「开/关」。
创建 Switch 开关
在学习该组件时,需要创建一个名为 Switch.vue 的文件,但是这个时候浏览器可能会产生警告,虽然不影响使用,可看着也不舒服。这是因为定义的组件名和 Element UI 中的组件名一致了,只需要将组件名改为 Switchs.vue 即可。
<template>
<div>
<h1>Switch开关的使用</h1>
<el-switch
v-model="value"
active-color="#13ce66"
inactive-color="#ff4949"
active-text="打开"
:active-value="true"
inactive-text="关闭"
:inactive-value="false">
</el-switch>
</div>
</template>
<script>
export default {
name: 'Switchs',
data() {
return {
value: true
}
}
}
</script>

Switch 的所有属性
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| value / v-model | 绑定值 | boolean / string / number | — | — |
| disabled | 是否禁用 | boolean | — | false |
| width | switch 的宽度(像素) | number | — | 40 |
| active-icon-class | switch 打开时所显示图标的类名,设置此项会忽略 active-text | string | — | — |
| inactive-icon-class | switch 关闭时所显示图标的类名,设置此项会忽略 inactive-text | string | — | — |
| active-text | switch 打开时的文字描述 | string | — | — |
| inactive-text | switch 关闭时的文字描述 | string | — | — |
| active-value | switch 打开时的值 | boolean / string / number | — | true |
| inactive-value | switch 关闭时的值 | boolean / string / number | — | false |
| active-color | switch 打开时的背景色 | string | — | #409EFF |
| inactive-color | switch 关闭时的背景色 | string | — | #C0CCDA |
| name | switch 对应的 name 属性 | string | — | — |
| validate-event | 改变 switch 状态时是否触发表单的校验 | boolean | - | true |
Switch 的事件和方法
事件:
| 事件名称 | 说明 | 回调参数 |
|---|---|---|
| change | switch 状态发生变化时的回调函数 | 新状态的值 |
方法:
| 方法名 | 说明 | 参数 |
|---|---|---|
| focus | 使 Switch 获取焦点 | - |
<h1>Switch事件与方法</h1>
<el-switch
v-model="aaa"
@change="bb"
active-value="on"
inactive-value="off"
ref="sw">
</el-switch>
<el-button @click="cc">调用方法</el-button>

4.6 DatePicker 日期选择器
用于选择或输入日期。
在 Element UI 中,提供了三种与时间日期相关的选择器,分别是:TimePicker(时间选择器)、DatePicker(日期选择器)和 DateTimePicker(日期时间选择器)。我们常用的是日期选择器,因此在此就介绍一些日期选择器。
创建 DatePicker 日期选择器
<template>
<div>
<h1>DatePicker日期选择器的使用</h1>
<el-date-picker
v-model="createTime">
</el-date-picker>
</div>
</template>
<script>
export default {
name: 'DatePicker',
data() {
return {
createTime:''
}
}
}
</script>

DatePicker 的属性
DatePicker 的属性有很多,完整属性列表可参考 DatePicker Attributes,常用属性如下表所示:
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| value / v-model | 绑定值 | date(DatePicker) / array(DateRangePicker) | — | — |
| readonly | 完全只读 | boolean | — | false |
| disabled | 禁用 | boolean | — | false |
| editable | 文本框可输入 | boolean | — | true |
| clearable | 是否显示清除按钮 | boolean | — | true |
| size | 输入框尺寸 | string | large, small, mini | — |
| placeholder | 非范围选择时的占位内容 | string | — | — |
| start-placeholder | 范围选择时开始日期的占位内容 | string | — | — |
| end-placeholder | 范围选择时结束日期的占位内容 | string | — | — |
| type | 显示类型 | string | year/month/date/dates/ week/datetime/datetimerange/ daterange/monthrange | date |
| format | 显示在输入框中的格式 | string | 见 日期格式 | yyyy-MM-dd |
| align | 对齐方式 | string | left, center, right | left |
| value-format | 可选,绑定值的格式。不指定则绑定值为 Date 对象 | string | 见 日期格式 | — |
注意: 当我们使用 <el-date-picker> 组件时,尽量指定 value-format 属性,同时,对应属性在数据库的字段类型设置成 timestamp,否则可能会造成添加的时间日期与真正存储的时间日期不一致。
readonly 和 disabled 最大的区别在于设置前者时,数据 会随着表单的提交而提交;而设置后者时,数据并 不会随着表单的提交而提交。
<template>
<div>
<h1>DatePicker日期选择器的使用</h1>
<el-date-picker
v-model="createTime"
:editable="false"
:clearable="false"
type="daterange"
start-placeholder="请输入开始时间"
end-placeholder="请输入结束时间"
format="yyyy/MM/dd">
</el-date-picker>
</div>
</template>
<script>
export default {
name: 'DatePicker',
data() {
return {
createTime:''
}
}
}
</script>

Picker Options 和 Shortcuts
Picker Options:用来对日期控件做自定义配置
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| shortcuts | 设置快捷选项,需要传入 { text, onClick } 对象用法参考 demo 或下表 | Object[] | — | — |
| disabledDate | 设置禁用状态,参数为当前日期,要求返回 Boolean | Function | — | — |
| cellClassName | 设置日期的 className | Function(Date) | — | — |
| firstDayOfWeek | 周起始日 | Number | 1 到 7 | 7 |
| onPick | 选中日期后会执行的回调,只有当 daterange 或 datetimerange 才生效 | Function({ maxDate, minDate }) | — | — |
Shortcuts:用来增加日期组件的快捷面板
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| text | 标题文本 | string | — | — |
| onClick | 选中后的回调函数,参数是 vm,可通过触发 ‘pick’ 事件设置选择器的值。例如 vm.$emit(‘pick’, new Date()) | function | — | — |
<h1>日期配置</h1>
<el-date-picker
v-model="createTime"
type="date"
placeholder="请输入时间"
:picker-options="pickerOptions">
</el-date-picker>
<script>
export default {
name: 'DatePicker',
data() {
return {
createTime:'',
pickerOptions: {
disabledDate(time) { // 对选择的日期进行配置
return time.getTime() > Date.now(); // 只能选择今天及以前
},
shortcuts: [{ // 定义的shortcuts
text: '今天',
onClick(picker) {
picker.$emit('pick', new Date());
}
}, {
text: '昨天',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24);
picker.$emit('pick', date);
}
}, {
text: '一周前',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', date);
}
}]
},
}
}
}
</script>
DatePicker 的事件
| 事件名称 | 说明 | 回调参数 |
|---|---|---|
| change | 用户确认选定的值时触发 | 组件绑定值。格式与绑定值一致,可受 value-format 控制 |
| blur | 当 input 失去焦点时触发 | 组件实例 |
| focus | 当 input 获得焦点时触发 | 组件实例 |
<el-date-picker
v-model="createTime"
@change="aaa">
</el-date-picker>
<script>
export default {
name: 'DatePicker',
data() {
return {
createTime:'',
}
},
methods: {
aaa(value) {
console.log(value);
}
}
}
</script>
4.7 Upload 上传
通过点击或者拖拽上传文件。
对应官方文档:Upload 上传
创建 Upload 上传
<template>
<div>
<h1>Upload组件的使用</h1>
<el-upload action="https://jsonplaceholder.typicode.com/posts/" :file-list="fileList">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">
只能上传jpg/png文件,且不超过500kb
</div>
</el-upload>
</div>
</template>
<script>
export default {
name: "Uploads",
data() {
return {
fileList: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}, {name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}]
};
},
};
</script>

注意: 在使用 <el-upload> 组件时,必须设置 action 属性,action 属性为必要参数且不能省略。
如果想实现拖拽上传,可以:
<h1>Upload拖拽上传</h1>
<el-upload
class="upload-demo"
drag
action="https://jsonplaceholder.typicode.com/posts/"
multiple>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>

Upload 的所有属性
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| action | 必选参数,上传的地址 | string | — | — |
| headers | 设置上传的请求头部 | object | — | — |
| multiple | 是否支持多选文件 | boolean | — | — |
| data | 上传时附带的额外参数 | object | — | — |
| name | 上传的文件字段名 | string | — | file |
| with-credentials | 支持发送 cookie 凭证信息 | boolean | — | false |
| show-file-list | 是否显示已上传文件列表 | boolean | — | true |
| drag | 是否启用拖拽上传 | boolean | — | false |
| accept | 接受上传的文件类型(thumbnail-mode 模式下此参数无效) | string | — | — |
| on-preview | 点击文件列表中已上传的文件时的钩子 | function(file) | — | — |
| on-remove | 文件列表移除文件时的钩子 | function(file, fileList) | — | — |
| on-success | 文件上传成功时的钩子 | function(response, file, fileList) | — | — |
| on-error | 文件上传失败时的钩子 | function(err, file, fileList) | — | — |
| on-progress | 文件上传时的钩子 | function(event, file, fileList) | — | — |
| on-change | 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用 | function(file, fileList) | — | — |
| before-upload | 上传文件之前的钩子,参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传 | function(file) | — | — |
| before-remove | 删除文件之前的钩子,参数为上传的文件和文件列表,若返回 false 或者返回 Promise 且被 reject,则停止删除 | function(file, fileList) | — | — |
| list-type | 文件列表的类型 | string | text/picture/picture-card | text |
| auto-upload | 是否在选取文件后立即进行上传 | boolean | — | true |
| file-list | 上传的文件列表, 例如: [{name: ‘food.jpg’, url: ‘https://xxx.cdn.com/xxx.jpg’}] | array | — | [] |
| http-request | 覆盖默认的上传行为,可以自定义上传的实现 | function | — | — |
| disabled | 是否禁用 | boolean | — | false |
| limit | 最大允许上传个数 | number | — | — |
| on-exceed | 文件超出个数限制时的钩子 | function(files, fileList) | — | - |
注意:
1、在使用 on-exceed 属性时,要结合 limit 属性使用。
2、在使用钩子时,需要使用 v-bind: 或者 : 进行绑定。
3、在使用 <el-upload> 组件时,没有 event 事件,所有事件都是属性事件。
Upload 的方法
| 方法名 | 说明 | 参数 |
|---|---|---|
| clearFiles | 清空已上传的文件列表(该方法不支持在 before-upload 中调用) | — |
| abort | 取消上传请求 | (file: fileList 中的 file 对象) |
| submit | 手动上传文件列表 | — |
<el-upload ref="uploads" ......>
......
</el-upload>
<el-button @click="clearFiles">清空文件</el-button>
<script>
export default {
name: "Uploads",
// ...
methods: {
clearFiles() {
this.$refs.uploads.clearFiles();
}
}
};
</script>
4.8 Form 表单
由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据。
对应官方文档:Form 表单
创建 Form 表单
根据官方文档的案例,经典的表单包括各种表单项,比如输入框、选择器、开关、单选框、多选框等。
<template>
<div>
<h1>Form组件的使用</h1>
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间">
<el-col :span="11">
<el-date-picker
type="date"
placeholder="选择日期"
v-model="form.date1"
style="width: 100%"
></el-date-picker>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-time-picker
placeholder="选择时间"
v-model="form.date2"
style="width: 100%"
></el-time-picker>
</el-col>
</el-form-item>
<el-form-item label="即时配送">
<el-switch v-model="form.delivery"></el-switch>
</el-form-item>
<el-form-item label="活动性质">
<el-checkbox-group v-model="form.type">
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="特殊资源">
<el-radio-group v-model="form.resource">
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="活动形式">
<el-input type="textarea" v-model="form.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: "Forms",
data() {
return {
form: {
name: "",
region: "",
date1: "",
date2: "",
delivery: false,
type: [],
resource: "",
desc: "",
},
};
},
methods: {
onSubmit() {
console.log("submit!");
},
},
};
</script>
<style>
</style>
在 Form 组件中,每一个表单域由一个 Form-Item 组件构成,表单域中可以放置各种类型的表单控件,包括 Input、Select、Checkbox、Radio、Switch、DatePicker、TimePicker 等组件。
如果想要创建内联表单,那么只需要将 <el-form> 的 inline 属性设置为 true 即可。如:
<el-form ref="form" :inline="true" :model="form" label-width="80px">
......
</el-form>
Form 的属性
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| model | 表单数据对象 | object | — | — |
| rules | 表单验证规则 | object | — | — |
| inline | 行内表单模式 | boolean | — | false |
| label-position | 表单域标签的位置,如果值为 left 或者 right 时,则需要设置 label-width | string | right/left/top | right |
| label-width | 表单域标签的宽度,例如 ‘50 px’。作为 Form 直接子元素的 form-item 会继承该值。支持 auto | string | — | — |
| label-suffix | 表单域标签的后缀 | string | — | — |
| hide-required-asterisk | 是否显示必填字段的标签旁边的红色星号 | boolean | — | false |
| show-message | 是否显示校验错误信息 | boolean | — | true |
| inline-message | 是否以行内形式展示校验信息 | boolean | — | false |
| status-icon | 是否在输入框中显示校验结果反馈图标 | boolean | — | false |
| validate-on-rule-change | 是否在 rules 属性改变后立即触发一次验证 | boolean | — | true |
| size | 用于控制该表单内组件的尺寸 | string | medium / small / mini | — |
| disabled | 是否禁用该表单内的所有组件。若设置为 true,则表单内组件上的 disabled 属性不再生效 | boolean | — | false |
表单的验证
Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。
表单验证包括两种情况:一是失去焦点就进行验证,另一种是表单提交调用表单组件的验证方法验证。
<el-form ref="form" :rules="rules" :model="form" label-width="80px">
<el-form-item label="活动名称" prop="name">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit('form')">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
<script>
export default {
name: "Forms",
data() {
return {
form: {
name: "",
},
rules: {
name: [
{ required: true, message: "请输入活动名称", trigger: "blur" },
{ min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" },
],
},
};
},
methods: {
onSubmit(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
alert('submit!');
} else {
console.log('error submit!!');
return false;
}
});
},
},
};
</script>

自定义验证规则
<h1>自定义验证规则</h1>
<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="80px" label-position="left">
<el-form-item label="密码" prop="pass">
<el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="确认密码" prop="checkPass">
<el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="年龄" prop="age">
<el-input v-model.number="ruleForm.age"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
<script>
export default {
data() {
var checkAge = (rule, value, callback) => {
if (!value) {
return callback(new Error('年龄不能为空'));
}
setTimeout(() => {
if (!Number.isInteger(value)) {
callback(new Error('请输入数字值'));
} else {
if (value < 18) {
callback(new Error('必须年满18岁'));
} else {
callback();
}
}
}, 1000);
};
var validatePass = (rule, value, callback) => {
if (value === '') {
callback(new Error('请输入密码'));
} else {
if (this.ruleForm.checkPass !== '') {
this.$refs.ruleForm.validateField('checkPass');
}
callback();
}
};
var validatePass2 = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入密码'));
} else if (value !== this.ruleForm.pass) {
callback(new Error('两次输入密码不一致!'));
} else {
callback();
}
};
return {
ruleForm: {
pass: '',
checkPass: '',
age: ''
},
rules: {
pass: [
{ validator: validatePass, trigger: 'blur' }
],
checkPass: [
{ validator: validatePass2, trigger: 'blur' }
],
age: [
{ validator: checkAge, trigger: 'blur' }
]
}
};
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
alert('submit!');
} else {
console.log('error submit!!');
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
}
}
}
</script>
自定义校验 callback 必须被调用。

5. 消息提示组件的使用
在 Element UI 中,消息提示组件的使用比较简单,建议参考官网文档进行编写。
5.1 Alert 警告
用于页面中展示重要的提示信息。
对应官方文档:Alert 警告
Alert 警告的使用
<template>
<div>
<h1>Alert组件的使用</h1>
<el-alert title="成功提示信息" type="success" description="我是辅助信息1号" :closable="false"></el-alert>
<br>
<el-alert title="消息提示信息" type="info" close-text="知道了" show-icon>
<div slot>我是辅助信息2号</div>
</el-alert>
<br>
<el-alert title="警告提示信息" type="warning" effect="dark" @close="hello" center></el-alert>
<br>
<el-alert title="错误提示信息" type="error" effect="light" show-icon center></el-alert>
</div>
</template>
<script>
export default {
name: 'Alerts',
methods: {
hello() {
alert('Hello World!');
}
}
}
</script>
<style>
</style>

5.2 Message 消息提示
常用于主动操作后的反馈提示。
对应官方文档:Message 消息提示
与 Notification 的区别是后者更多用于系统级通知的被动提醒。
但在这我们并不介绍 Notification,可以自行查看官方文档:Notification 通知
Message 消息提示的使用
注意: 这个组件的创建无须在页面中书写任何标签,它是一个 JS 插件,在需要展示消息提示的位置直接调用提供的 JS 插件即可。
<template>
<div>
<h1>Message组件的使用</h1>
<el-button type="success" @click="open2">成功</el-button>
<el-button type="warning" :plain="true" @click="open3">警告</el-button>
<el-button type="primary" :plain="true" @click="open1">消息</el-button>
<el-button type="danger" @click="open4">错误</el-button>
<el-button :plain="true" ref="close" @click="closeMsg">调用关闭提示方法</el-button>
</div>
</template>
<script>
export default {
name: "Messages",
methods: {
open1() {
this.$message("这是一条消息提示")
},
open2() {
const h = this.$createElement;
this.$message({
message: h("p", null, [
h("span", null, "内容可以是 "),
h("i", { style: "color: teal" }, "Success"),
]),
type: "success",
duration: 0,
});
},
open3() {
this.$message({
showClose: "true",
message: "警告哦,这是一条警告消息",
type: "warning",
center: "true",
});
},
open4() {
this.$message.error("错了哦,这是一条错误消息");
},
closeMsg() { // 关闭所有消息提示
this.$message.closeAll();
}
},
};
</script>
<style>
</style>


Element UI 注册了一个 $message 方法用于调用,Message 可以接收一个字符串或一个 VNode 作为参数,它会被显示为正文内容。
当需要自定义更多属性时,Message 也可以接收一个对象为参数。比如,设置 type 字段可以定义不同的状态,默认为 info。此时正文内容以 message 的值传入。同时,我们也为 Message 的各种 type 注册了方法,可以在不传入 type 字段的情况下像 open4 那样直接调用。
默认的 Message 是不可以被人工关闭的,如果需要可手动关闭的 Message,可以使用 showClose 字段。此外,和 Notification 一样,Message 拥有可控的 duration,设置 0 为不会被自动关闭,默认为 3000 毫秒。
其他属性:
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| type | 主题 | string | success/warning/info/error | info |
| iconClass | 自定义图标的类名,会覆盖 type | string | — | — |
| dangerouslyUseHTMLString | 是否将 message 属性作为 HTML 片段处理 | boolean | — | false |
| customClass | 自定义类名 | string | — | — |
| onClose | 关闭时的回调函数, 参数为被关闭的 message 实例 | function | — | — |
| offset | Message 距离窗口顶部的偏移量 | number | — | 20 |
Message 的完整属性参考:Options
将 dangerouslyUseHTMLString 属性设置为 true,message 就会被当作 HTML 片段处理。参考:Message 使用 HTML 片段
注意: message 属性虽然支持传入 HTML 片段,但是在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。因此在 dangerouslyUseHTMLString 打开的情况下,请确保 message 的内容是可信的,永远不要 将用户提交的内容赋值给 message 属性。 简单来说,最好别用这玩意。 😓
6. Table 表格
用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。
Table 表格组件是作为 Data 数据组件的一项,数据组件中还有很多其他的组件,比如分页、树形控件等。表格组件在日常开发中会经常使用到,因此单独提出来进行讲解。
6.1 创建 Table 表格
创建一个表格需要使用到 <el-table> 组件。当 el-table 元素中注入 data 对象数组后,在 el-table-column 中用 prop 属性来对应对象中的键名即可填入数据,用 label 属性来定义表格的列名。可以使用 width 属性来定义列宽。
<template>
<div>
<h1>Table组件的使用</h1>
<el-table :data="tableData">
<el-table-column prop="id" label="编号"></el-table-column>
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="age" label="年龄"></el-table-column>
<el-table-column prop="email" label="邮箱"></el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: 'Tables',
data() {
return {
tableData: [
{id: 1, name: "mofan", age: 18, email: "cy.mofan@qq.com"},
{id: 2, name: "默烦", age: 20, email: "cy.mofan@qq.com"},
]
}
}
}
</script>

6.2 表格的列属性
表格的完整列属性参看:Table-column Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| width | 对应列的宽度 | string | — | — |
| fixed | 列是否固定在左侧或者右侧,true 表示固定在左侧 | string, boolean | true, left, right | — |
| align | 对齐方式 | String | left/center/right | left |
| header-align | 表头对齐方式,若不设置该项,则使用表格的对齐方式 | String | left/center/right | — |
| sortable | 对应列是否可以排序,如果设置为 ‘custom’,则代表用户希望远程排序,需要监听 Table 的 sort-change 事件 | boolean, string | true, false, ‘custom’ | false |
| sort-method | 对数据进行排序的时候使用的方法,仅当 sortable 设置为 true 的时候有效,需返回一个数字,和 Array.sort 表现一致 | Function(a, b) | — | — |
| resizable | 对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真) | boolean | — | true |
| formatter | 用来格式化内容 | Function(row, column, cellValue, index) | — | — |
对于 fixed 属性可以理解为自适应,当其设置为 left 时,还会取决于 width 属性值,但是设置为 right 时,不会取决于 width 属性值。
align 可以设置列中内容的对齐方式,包括表头和表内数据。如果只想设置表内数据的对齐方式,可以使用 header-align 设置表头的对齐方式。
<template>
<div>
<h1>Table组件的使用</h1>
<el-table :data="tableData" border>
<el-table-column
prop="id"
:resizable="false"
header-align="left"
align="center"
label="编号"
width="200px"
></el-table-column>
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column
prop="age"
label="年龄"
:sort-method="sorts"
sortable
></el-table-column>
<el-table-column prop="email" label="邮箱"></el-table-column>
<el-table-column
prop="dept.name"
:formatter="showDept"
label="部门"
></el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: "Tables",
data() {
return {
tableData: [
{
id: 1,
name: "mofan",
age: 18,
email: "cy.mofan@qq.com",
dept: {
id: 1,
name: "研发",
},
},
{
id: 2,
name: "默烦",
age: 20,
email: "cy.mofan@qq.com",
dept: {
id: 2,
name: "财务",
},
},
{
id: 3,
name: "小陈",
age: 22,
email: "cy.mofan@qq.com",
dept: {},
},
],
};
},
methods: {
sorts(a, b) {
console.log(a);
console.log(b);
return b.age - a.age; // 注意交换顺序后的区别
},
showDept(row, column, cellValue, index) {
console.log(row);
console.log(column);
console.log(cellValue);
console.log(index);
if (cellValue) {
return cellValue;
} else {
return "暂无部门";
}
},
},
};
</script>

6.3 表格的属性
表格的完整属性参看:Table Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| data | 显示的数据 | array | — | — |
| height | Table 的高度,默认为自动高度。如果 height 为 number 类型,单位 px;如果 height 为 string 类型,则这个高度会设置为 Table 的 style.height 的值,Table 的高度会受控于外部样式 | string/number | — | — |
| max-height | Table 的最大高度。合法的值为数字或者单位为 px 的高度 | string/number | — | — |
| stripe | 是否为斑马纹 table | boolean | — | false |
| size | Table 的尺寸 | string | medium / small / mini | — |
| border | 是否带有纵向边框 | boolean | — | false |
| fit | 列的宽度是否自撑开 | boolean | — | true |
| show-header | 是否显示表头 | boolean | — | true |
| highlight-current-row | 是否要高亮当前行 | boolean | — | false |
| row-class-name | 行的 className 的回调方法,也可以使用字符串为所有行设置一个固定的 className | Function({row, rowIndex})/String | — | — |
| empty-text | 空数据时显示的文本内容,也可以通过 slot="empty" 设置 | String | — | 暂无数据 |
使用 row-class-name 可以指定每一行的回调方法,也可以直接指定固定的 className。比如,可以给每一行指定不同的样式(设置不同的底色),但是在设置不同的底色时 最好移除 属性 stripe,使用这个属性很有可能会让我们设置的样式无法显示。
在使用 empty-text 属性时,空数据时显示的文本内容,指的是 整个表没有数据 时显示的文本内容。
本次的案例建立在 6.2 表格的列属性 demo 的基础上:
<el-table
:data="tableData"
border
:fit="false"
:height="400"
size="small"
:highlight-current-row="true"
:row-class-name="showCss"
:show-header="false">
</el-table>
<script>
export default {
name: "Tables",
data() {
return {
// 省略已写代码
};
},
methods: {
// 省略以写代码
showCss({row, rowIndex}) {
if(rowIndex % 2 == 0) {
return "warning-row";
} else {
return "success-row";
}
},
},
};
</script>
<style>
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
6.4 事件与方法
表格的完整事件参看:Table Events
表格的事件:
| 事件名 | 说明 | 参数 |
|---|---|---|
| select | 当用户手动勾选数据行的 Checkbox 时触发的事件 | selection, row |
表格的事件有很多,学会使用思路就行。
<el-table @select="selectRow"></el-table>
<!-- 省略已写代码 -->
<script>
export default {
name: "Tables",
data() {
return {
// 省略已写代码
};
},
methods: {
// 省略已写代码
selectRow(selection, row) {
console.log(selection); // 被选中的所有行
console.log(row); // 本次选中的行
}
},
};
</script>
表格的方法:
表格的完整事件参看:Table Methods
| 方法名 | 说明 | 参数 |
|---|---|---|
| clearSelection | 用于多选表格,清空用户的选择 | — |
表格的方法有很多,学会使用思路就行。
<el-table ref="mytable">
<!-- 省略已写代码 -->
</el-table>
<el-button type="primary" @click="clearSelect">清空表格</el-button>
<script>
export default {
name: "Tables",
data() {
return {
// 省略已写代码
};
},
methods: {
// 省略已写代码
clearSelect() {
this.$refs.mytable.clearSelection();
}
},
};
</script>
6.5 自定义操作列
一般来说,一个表格中还有一列操作列,在这一列中可以编辑、删除数据。
<el-table>
<!-- 省略已写代码 -->
<el-table-column label="操作">
<template slot-scope="scope">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">
编辑
</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<script>
export default {
name: "Tables",
data() {
return {
// 省略已写代码
};
},
methods: {
// 省略已写代码
handleEdit(index, row) {
console.log(index, row);
},
handleDelete(index, row) {
console.log(index, row);
}
},
};
</script>

6.6 自定义表头
有时候我们还想自定义表头,比如在表头上添加一个搜索栏。
<el-table :data="tableData.filter(data => !search || data.name.toLowerCase().includes(search.toLowerCase()))">
<el-table-column type="selection"></el-table-column>
<!-- 省略其他代码 -->
<el-table-column align="right">
<template slot="header" slot-scope="scope">
<el-input v-model="search" size="mini" placeholder="输入关键字搜索" />
</template>
<template slot-scope="scope">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">
编辑
</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<script>
export default {
name: "Tables",
data() {
return {
// 省略已写代码
};
},
methods: {
// 省略已写代码
handleEdit(index, row) {
console.log(index, row);
},
handleDelete(index, row) {
console.log(index, row);
}
},
};
</script>

Element UI 中 Table 表格的内容有很多,在此只介绍思想,详情参考官方文档:Table 表格
7. 小案例讲解
7.1 项目搭建
执行以下命令,初始化项目:
vue init webpack element_users
等待初始化完毕后,下载 Element UI 的依赖:
npm i element-ui -S
等待下载完毕后,在 main.js 文件中引入并使用 Element UI:
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 在 Vue 脚手架中使用 Element UI
Vue.use(ElementUI);
然后在 assets 目录下创建名为 indexImgs 的文件夹,向里面塞六张图片,作为首页轮播图。
还会使用到 Axios,因此需要进行安装:
在项目的根目录中,执行以下命令,安装 Axios:
npm install axios --save
等待安装完毕后,前往 main.js 文件,添加以下代码:
// 引入 Axios
import axios from 'axios'
// 修改内部的 $http 为 axios
Vue.prototype.$http = axios
7.2 页面导航菜单
<template>
<div id="app">
<el-container>
<el-header>
<!-- 导航菜单 -->
<el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
<el-menu-item index="/index">主页</el-menu-item>
<el-menu-item index="/users" >用户管理</el-menu-item>
<el-menu-item index="/msgs">消息中心</el-menu-item>
<el-menu-item index="/orders">订单管理</el-menu-item>
</el-menu>
</el-header>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
activeIndex: '/index',
};
},
methods: {
handleSelect(key, keyPath) {
this.$router.push(key);
}
}
}
</script>
7.3 首页轮播图
创建一个名为 Index.vue 的组件,该组件主要用于主页显示。在 index.js 中注册组件:
import Vue from 'vue'
import Router from 'vue-router'
import Index from '../components/Index.vue'
import List from '../components/user/List.vue'
Vue.use(Router)
export default new Router({
routes: [{
path: '/',
redirect: '/index',
},
{
path: '/index',
component: Index
},
{
path: '/users',
component: List
}
]
})
// 解决 ElementUI 导航栏中的 vue-router 在 3.0 版本以上重复点菜单报错问题
const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
就这一次哦,以后就省略组件的注册了。😊
然后在 Index.vue 中编写主页轮播图的代码:
<template>
<div>
<el-carousel indicator-position="outside" height="500px">
<el-carousel-item v-for="item in imgs" :key="item">
<el-image :src="item" fit="contain" style="height: 600px"></el-image>
</el-carousel-item>
</el-carousel>
</div>
</template>
<script>
import homeImg1 from '../assets/indexImgs/1.jpg'
import homeImg2 from '../assets/indexImgs/2.jpg'
import homeImg3 from '../assets/indexImgs/3.jpg'
import homeImg4 from '../assets/indexImgs/4.jpg'
import homeImg5 from '../assets/indexImgs/5.jpg'
import homeImg6 from '../assets/indexImgs/6.jpg'
export default {
name: "Index",
data() {
return {
imgs: [
homeImg1, homeImg2, homeImg3, homeImg4, homeImg5, homeImg6
],
};
},
};
</script>
7.4 用户管理界面
创建 List.vue 作为用户管理界面的组件。
<template>
<div>
<el-table :data="tableData.filter(data => !search || data.name.toLowerCase().includes(search.toLowerCase()))" style="width: 100%">
<el-table-column label="编号" width="180">
<template slot-scope="scope">
<span style="margin-left: 10px"> {{ scope.row.id }} </span>
</template>
</el-table-column>
<el-table-column label="姓名" width="180">
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
<p>姓名: {{ scope.row.name }}</p>
<p>住址: {{ scope.row.address }}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium">{{ scope.row.name }}</el-tag>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column label="生日" prop="birth"></el-table-column>
<el-table-column label="性别" prop="gender"></el-table-column>
<el-table-column label="地址" prop="address"></el-table-column>
<el-table-column align="right">
<template slot="header" slot-scope="scope">
<el-input
v-model="search"
size="mini"
placeholder="输入姓名的关键字进行搜索"/>
</template>
<template slot-scope="scope">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-button type="success" style="margin-top: 10px" size="mini">添加</el-button>
</div>
</template>
<script>
export default {
name: "List",
data() {
return {
tableData: [
{
id: 1,
name: "王小虎",
birth: '2016-05-02',
address: "上海市",
gender: '男',
},
{
id: 2,
name: "默烦",
birth: '2000-01-01',
address: "成都市",
gender: '男',
},
],
search: '',
};
},
methods: {
handleEdit(index, row) {
console.log(index, row);
},
handleDelete(index, row) {
console.log(index, row);
},
},
};
</script>

7.5 用户管理后端编写
使用 IDEA 创建一个 SpringBoot 项目或 Module,并引入一下依赖:
Spring Boot DevTools Lombok Spring Web MyBatis Framework MySQL Driver
新建数据库,在库内新建一张表:
CREATE TABLE `t_user` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`name` varchar(80) DEFAULT NULL,
`birth` timestamp NULL DEFAULT NULL,
`gender` varchar(4) DEFAULT NULL,
`address` varchar(120) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
注意: 这里 birth 的类型设置成了 timestamp,如果设置成 date 类型,可能会导致后续存储的数据和界面显示的数据不一致。
项目配置文件:
server:
port: 9090
servlet:
context-path: /
spring:
datasource:
password: 123456
type: com.alibaba.druid.pool.DruidDataSource
username: root
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/elementusers?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8
mybatis:
mapper-locations: classpath:indi/mofan/mapper/*.xml
type-aliases-package: indi.mofan.entity
主要实体类:
/**
* @author mofan 2021/1/16
*/
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Accessors(chain = true)
public class User {
private String id;
private String name;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date birth;
private String gender;
private String address;
}
数据访问层:
/**
* @author mofan 2021/1/16
*/
@Mapper
@Repository
public interface UserDao {
/**
* 查询所有用户信息
* @return
*/
List<User> findAll();
/**
* 添加用户
* @param user
*/
void save(User user);
/**
* 更新用户信息
* @param user
*/
void update(User user);
/**
* 删除某一用户信息
* @param id
*/
void delete(String id);
/**
* 分页查询
* @param start
* @param rows
* @return
*/
List<User> findByPage(@Param("start") Integer start,
@Param("rows") Integer rows);
/**
* 查询总条数
* @return
*/
Long findTotals();
}
对应的 MyBatis 映射文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="indi.mofan.dao.UserDao">
<select id="findAll" resultType="indi.mofan.entity.User">
select id, name, birth, gender, address
from t_user
</select>
<insert id="save" useGeneratedKeys="true" keyProperty="id">
insert into t_user values(#{id}, #{name}, #{birth}, #{gender}, #{address})
</insert>
<update id="update">
update t_user
set name = #{name}, birth=#{birth}, gender=#{gender}, address=#{address}
where id = #{id}
</update>
<delete id="delete">
delete from t_user where id = #{id}
</delete>
<!-- 分页查询 -->
<select id="findByPage" resultType="indi.mofan.entity.User">
select id, name, birth, gender, address
from t_user limit #{start}, #{rows}
</select>
<select id="findTotals" resultType="long">
select count(*) from t_user
</select>
</mapper>
业务层实现类:
/**
* @author mofan 2021/1/16
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
@Transactional(readOnly = true)
public List<User> findAll() {
return userDao.findAll();
}
@Override
public void save(User user) {
userDao.save(user);
}
@Override
public void update(User user) {
userDao.update(user);
}
@Override
public void delete(String id) {
userDao.delete(id);
}
@Override
public List<User> findByPage(Integer pageNow, Integer rows) {
int start = (pageNow - 1) * rows;
return userDao.findByPage(start, rows);
}
@Override
public Long findTotals() {
return userDao.findTotals();
}
}
控制层:
import com.alibaba.druid.util.StringUtils;
/**
* @author mofan 2021/1/16
*/
@RestController
@RequestMapping("user")
@CrossOrigin
public class UserController {
@Autowired
private UserService userService;
@GetMapping("findAll")
public List<User> findAll() {
return userService.findAll();
}
@PostMapping("saveOrUpdate")
public Map<String, Object> saveOrUpdate(@RequestBody User user) {
Map<String, Object> map = new HashMap<>(8);
try {
if (StringUtils.isEmpty(user.getId())){
userService.save(user);
map.put("success", true);
map.put("msg", "添加用户信息成功");
} else {
userService.update(user);
map.put("success", true);
map.put("msg", "修改用户信息成功");
}
} catch (Exception e) {
map.put("success", false);
map.put("msg", "用户信息提交失败" + e.getMessage());
}
return map;
}
@GetMapping("delete")
public Map<String, Object> delete(String id) {
Map<String, Object> map = new HashMap<>(8);
try {
userService.delete(id);
map.put("success", true);
map.put("msg", "删除用户信息成功");
} catch (Exception e) {
map.put("success", false);
map.put("msg", "删除用户信息失败" + e.getMessage());
}
return map;
}
@GetMapping("findByPage")
public Map<String, Object> findByPage(Integer pageNow, Integer pageSize) {
Map<String, Object> map = new HashMap<>(16);
pageNow = pageNow == null ? 1 : pageNow;
pageSize = pageSize == null ? 4 : pageSize;
List<User> users = userService.findByPage(pageNow, pageSize);
Long totals = userService.findTotals();
map.put("users", users);
map.put("total", totals);
return map;
}
}
后端搞定! 😎
7.6 前端页面完善
<template>
<div>
<el-table
:data="
tableData.filter(
(data) =>
!search || data.name.toLowerCase().includes(search.toLowerCase())
)
"
style="width: 100%"
>
<el-table-column label="编号" width="180">
<template slot-scope="scope">
<span style="margin-left: 10px"> {{ scope.row.id }} </span>
</template>
</el-table-column>
<el-table-column label="姓名" width="180">
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
<p>姓名: {{ scope.row.name }}</p>
<p>住址: {{ scope.row.address }}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium">{{ scope.row.name }}</el-tag>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column label="生日" prop="birth"></el-table-column>
<el-table-column label="性别" prop="gender"></el-table-column>
<el-table-column label="地址" prop="address"></el-table-column>
<el-table-column align="right">
<template slot="header" slot-scope="scope">
<el-input
v-model="search"
size="mini"
placeholder="输入姓名的关键字进行搜索"
/>
</template>
<template slot-scope="scope">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)"
>编辑</el-button
>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<el-row>
<el-col :span="12" :offset="12">
<!-- 分页组件 -->
<el-pagination
style="margin: 15px 0px"
prev-text="上一页"
next-text="下一页"
background
layout="prev, pager, next, jumper, total, sizes"
:page-size="size"
:current-page="pageNow"
:page-sizes="[2, 4, 6, 8, 10]"
@current-change="findPage"
@size-change="findSize"
:total="total"
>
</el-pagination
></el-col>
</el-row>
<el-button
type="success"
style="margin-top: 10px"
size="mini"
@click="dialogFormVisible = true"
>添加</el-button
>
<!-- 添加用户表单 -->
<el-dialog
title="用户信息"
:visible.sync="dialogFormVisible"
width="40%"
:close-on-click-modal="false"
@close="addDialogClose"
>
<el-form
:model="user"
ref="formRef"
:hide-required-asterisk="false"
:rules="rules"
>
<el-form-item label="姓名" :label-width="formLabelWidth" prop="name">
<el-input v-model="user.name" style="width: 220px"></el-input>
</el-form-item>
<el-form-item label="性别" :label-width="formLabelWidth" prop="gender">
<el-radio v-model="user.gender" label="男">男</el-radio>
<el-radio v-model="user.gender" label="女">女</el-radio>
</el-form-item>
<el-form-item label="生日" :label-width="formLabelWidth" prop="birth">
<el-date-picker
v-model="user.birth"
type="date"
placeholder="请选择你的生日"
value-format="yyyy-MM-dd"
>
</el-date-picker>
</el-form-item>
<el-form-item label="地址" :label-width="formLabelWidth" prop="address">
<el-input v-model="user.address" style="width: 220px"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="submitUserInfo('formRef')"
>提 交</el-button
>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "List",
data() {
return {
tableData: [],
search: "",
dialogFormVisible: false,
user: {
name: "",
gender: "男",
birth: "",
address: "",
},
formLabelWidth: "120px",
total: 0,
size: 4,
pageNow: 1,
rules: {
name: [
{ required: true, message: "请输入用户的名称", trigger: "blur" },
],
birth: [
{ required: true, message: "请输入用户的出生日期", trigger: "blur" },
],
address: [
{ required: true, message: "请输入用户的地址", trigger: "blur" },
],
},
};
},
methods: {
handleEdit(index, row) {
this.user = row;
this.dialogFormVisible = true;
},
handleDelete(index, row) {
this.delRow(row.id);
},
// 更新用户信息或添加用户信息
submitUserInfo(formRef) {
this.$refs[formRef].validate((valid) => {
if (valid) {
this.saveOrUpdateUserInfo();
} else {
this.$message.error("请输入正确的数据");
return false;
}
});
},
// 关闭表单的回调
addDialogClose() {
this.$refs.formRef.resetFields(); // 清空表单
this.user = {};
},
getUserList(page, size) {
page = page ? page : this.pageNow;
size = size ? size : this.size;
this.$http
.get(
"http://localhost:9090/user/findByPage?pageNow=" +
page +
"&pageSize=" +
size
)
.then((res) => {
this.tableData = res.data.users;
this.total = res.data.total;
});
},
saveOrUpdateUserInfo() {
this.$http
.post("http://localhost:9090/user/saveOrUpdate", this.user)
.then((res) => {
if (res.data.success) {
// 关闭对话框
this.dialogFormVisible = false;
this.$refs.formRef.resetFields(); // 清空表单
this.user = {};
this.showMsg(res.data.msg);
this.getUserList(this.pageNow, this.size);
}
});
},
delRow(id) {
this.$confirm("此操作将删除选中用户, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.$http
.get("http://localhost:9090/user/delete?id=" + id)
.then((res) => {
if (res.data.success == true) {
this.getUserList(); // 查询所有用户
this.showMsg(res.data.msg);
}
});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除",
});
});
},
showMsg(msg) {
this.$message({
message: msg,
type: "success",
});
},
// 用来处理分页的相关方法
findPage(page) {
this.pageNow = page;
this.getUserList(page, this.size);
},
// 用来处理每页显示的记录
findSize(size) {
this.size = size;
this.getUserList(this.pageNow, size);
},
},
created() {
this.getUserList();
},
};
</script>
<style>
</style>
注意: 时间选择器组件 <el-date-picker> 使用了属性 value-format="yyyy-MM-dd",请务必使用该属性,否则会造成后续存储的时间和界面显示的时间不一致。
这样,关于用户的增删改查就完成了,并且还用到了前面没有讲解的一些组件,比如 Dialog 对话框、Pagination 分页等。
可以在浏览器地址栏输入 http://localhost:8080/#/users 以访问界面。:punch:

8. Pagination 分页
当数据量过多时,使用分页分解数据。
Pagination 分页组件是作为 Data 数据组件的一项,数据组件中还有很多其他的组件,比如前面讲解的 Table 表格就是其中之一。
我们已经在 7. 小案例讲解 中使用了分页组件,在此列举一些分页组件常用的属性与方法。
具体使用请参考文档:Pagination
Pagination 的完整属性
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| small | 是否使用小型分页样式 | boolean | — | false |
| background | 是否为分页按钮添加背景色 | boolean | — | false |
| page-size | 每页显示条目个数,支持 .sync 修饰符 | number | — | 10 |
| total | 总条目数 | number | — | — |
| page-count | 总页数,total 和 page-count 设置任意一个就可以达到显示页码的功能;如果要支持 page-sizes 的更改,则需要使用 total 属性 | Number | — | — |
| pager-count | 页码按钮的数量,当总页数超过该值时会折叠 | number | 大于等于 5 且小于等于 21 的奇数 | 7 |
| current-page | 当前页数,支持 .sync 修饰符 | number | — | 1 |
| layout | 组件布局,子组件名用逗号分隔 | String | sizes, prev, pager, next, jumper, ->, total, slot | ’prev, pager, next, jumper, ->, total’ |
| page-sizes | 每页显示个数选择器的选项设置 | number[] | — | [10, 20, 30, 40, 50, 100] |
| popper-class | 每页显示个数选择器的下拉框类名 | string | — | — |
| prev-text | 替代图标显示的上一页文字 | string | — | — |
| next-text | 替代图标显示的下一页文字 | string | — | — |
| disabled | 是否禁用 | boolean | — | false |
| hide-on-single-page | 只有一页时是否隐藏 | boolean | — | - |
Pagination 的完整事件
| 事件名称 | 说明 | 回调参数 |
|---|---|---|
| size-change | pageSize 改变时会触发 | 每页条数 |
| current-change | currentPage 改变时会触发 | 当前页 |
| prev-click | 用户点击上一页按钮改变当前页后触发 | 当前页 |
| next-click | 用户点击下一页按钮改变当前页后触发 | 当前页 |
好了,这基本就是 Element UI 的全部内容了,当然了本文只做思路讲解,还有许多的内容没有讲解到,具体的使用还是参看 官方文档 更舒服。😉
Element UI 使用思路完