目录
Element-ui
官方文档地址: https://element.eleme.cn/#/zh-CN/component/installation
1 Element-ui概述
Element-ui,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的组件库,提供了配套设计资源,帮助你的网站快速成型。由饿了么公司前端团队开源。
element-ui的上手使用还是挺容易的,在理想情况下,只需要以下步骤:
- 找想要的样式组件
- 复制代码到对应的
.vue
组件 - 修改对应的数据
1.1 Element-ui介绍及文档
非组件样式
官方提供的样式中有一部分并非是组件样式,比如:字体图标、全局指令、全局事件等,这里简单说明下这类样式的使用方法
-
图标样式
一般情况下,使用
i
标签,并将class
属性设置成对应的图标名即可;而对于别的组件希望引入图标时(可使用icon
属性,例如el-button
),设置icon
属性为对应的图标名。 -
指令样式
例如
Loading加载
,其提供的是一个指令v-loading
,使用时直接调用就行。
<el-table v-loading='true' :data="tableData">
<el-table-column prop="name" label="姓名">
</el-table>
-
事件样式
例如
Message消息提示
,结合事件使用。
<el-button :plain="true" @click="successMessage">成功</el-button>
<el-button :plain="true" @click="warnMessage">警告</el-button>
<el-button :plain="true" @click="infoMessage">普通消息</el-button>
<el-button :plain="true" @click="errorMessage">错误</el-button>
errorMessage(){
this.$message({
message: "错误消息",
type: "error"
})
},
infoMessage(){
this.$message("普通消息")
},
successMessage(){
this.$message({
message: "成功信息",
type: "success"
})
},
warnMessage(){
this.$message({
message: "警告信息",
type:"warning"
})
},
参考文档
element-ui文档提供了很多示例代码,一般情况下我们直接拷下示例代码稍微改改数据就够用了。但是在某些场景下,我们可能又需要使用到一些特殊的功能和属性,而这些功能属性一般在官方提供的组件中都已经内置了,所以我们可以直接先从文档
中查看是否有属性或者方法能够满足我们的需求,避免重复造轮子。下面就是 文档里提供的一些属性、方法
-
attribute
官方提供的属性,使用时,直接设置属性和值就行,如
el-input
组件,其属性有maxlength
(最大输入长度,number
型)和clearable
(是否可清空,boolean
型),对于非boolean
型的属性,需要直接设置值的内容;对于boolean
型的属性,一般默认是false
,而直接添加该属性,默认为true
,<template> <div> <el-input v-model="name" maxlength="10" clearable></el-input> <!-- 最大长度为10,设置可清空,添加clearable即默认为true,等同于:clearable="true" --> </div> </template>
-
slot
slot
插槽的使用和普通的slot
用法没什么区别,直接在组件中设置slot属性即可,如el-input
组件,其Input slots下提供了prepend
(输入框头部内容),下面是slot
的代码示例:<template> <div> <el-input> <label slot="prepend">用户名:</label> <!-- 设置slot属性为对应的值,prepend 前缀 ; append 后缀 --> </el-input> </div> </template>
设置样式,必须在el-form 组件中,单独设置一个el-input 无效。
-
event
event就是监听事件,直接使用
v-on
(简写@
)绑定该event,例如el-input
组件的Input Events下提供了change
事件,并且回调中的参数包括value
时,那么该事件将会传递这个参数的值,例如:
<template>
<div>
<!-- 监听change事件 -->
<el-input @change="handleChange" v-model="name">
<label slot="prepend">用户名:</label>
<!-- 设置slot为对应的值 -->
</el-input>
</div>
</template>
<script>
export default {
data() {
return {
name: "zhangsan"
};
},
methods: {
handleChange(value) {
// 监听事件的处理方法,回调时会获取到修改后的值, 失焦时触发
alert(`值被修改为:${value}`);
}
}
};
</script>
-
method
组件内置的方法,使用时可以通过
组件自身
调用,使用步骤如下:-
组件设置
ref
属性 -
通过
this.$refs.ref属性名.方法()
调用组件自身的method方法例如
el-input
组件提供了focus()
方法,获取焦点。 例如:
-
<template>
<div>
<!-- 监听change事件 -->
<el-input @change="handleChange" v-model="name" ref="nameInput">
<label slot="prepend">用户名:</label>
</el-input>
<el-button @click="handle">input组件 获取焦点</el-button>
</div>
</template>
<script>
export default {
data() {
return {
name: "zhangsan"
};
},
methods: {
handle() {
this.$refs.nameInput.focus();
// 调用focus方法聚焦到对应的input组件
}
}
};
</script>
> 这里实际上就是父组件调用子组件 方法 的场景
-
option
一些attribute值为
object
类型时,option为该attribute对象里的键值参考,这里拿el-time-select
组件(时间选择器)举例,该组件里的picker-options
属性是object
类型,而文档也提供了Time Select Options的参数说明,下面是使用示例:
<template>
<div>
<el-time-select
v-model="value1"
:picker-options="{
start: '08:30',
step: '00:15',
end: '18:30'
}"
></el-time-select>
<!-- picker-options是object类型,option里则提供了各种该对象里的参数 -->
</div>
</template>
<script>
export default {
data() {
return {
value1: ""
};
}
};
</script>
-
子组件
很多的组件里都含有
子组件
,比如el-select
下拉组件有子组件el-option
,使用时将其嵌套在父组件,而对应子组件的attributes
、slot
等的使用方式也是一样的,例如:<template> <div> <!-- 下拉选框 --> <el-select v-model="value" placeholder="请选择"> <el-option v-for="item in options" :key="item.id" :label="item.label" :value="item.value"></el-option> <!-- 子组件el-option嵌套在父组件el-select中,其他都像普通组件一样使用 --> </el-select> </div> </template> <script> export default { data() { return { options: [ { id: 1, value: "zz", label: "郑州" }, { id: 2, value: "bj", label: "北京" } ], value: "", //el-option选中的值 如 zz }; } }; </script>
2 Element-UI安装及配置
安装
npm install --save element-ui
在main.js下配置element-ui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
3 Element-ui布局
3.1 Layout 布局
通过基础的 24 分栏(列),迅速简便地创建布局。
-
基础布局
通过 row 和 col 组件,及col 组件的
span
(列的跨度)属性 创建基础的栅格布局
<!-- 栅格布局 -->
<el-row>
<!-- span 为3 表示跨3列 共24列-->
<el-col :span="3">
<div class="grid-content1">
栅格布局1
</div>
</el-col>
<el-col :span="10">
<div class="grid-content2">
栅格布局2
</div>
</el-col>
</el-row>
-
列的间隔
Row 组件 提供
gutter
属性来指定每一栏之间的间隔,默认间隔为 0。
<!-- gutter 在列之间设置间隔 -->
<el-row :gutter="20">
<el-col :span="6">
<div class="grid-content1 bg-purple">
第一列
</div>
</el-col>
<el-col :span="6">
<div class="grid-content1 bg-purple">
第二列
</div>
</el-col>
<el-col :span="6">
<div class="grid-content1 bg-purple">
第三列
</div>
</el-col>
<el-col :span="6">
<div class="grid-content1 bg-purple">
第四列
</div>
</el-col>
</el-row>
-
混合布局
通过基础的 1/24 分栏任意组合形成较为复杂的混合布局。
<!-- 混合布局 -->
<el-row :gutter="20">
<el-col :span="16">
<div class="grid-content1 bg-purple">
第一列
</div>
</el-col>
<el-col :span="8">
<div class="grid-content2 bg-purple">
第二列
</div>
</el-col>
</el-row>
-
分栏偏移 offset属性
每栏 支持偏移指定的栏数
<!-- gutter 列之间的距离
span 跨的列数, 共24列
-->
<el-row :gutter="20">
<el-col :span="6">
<div class="grid-content1 bg-purple">
第一列
</div>
</el-col>
<el-col :span="6" :offset="6">
<div class="grid-content2 bg-purple">
第二列
</div>
</el-col>
</el-row>
-
对齐方式
通过
flex
布局来对分栏进行灵活的对齐。
<!-- 一般的布局 -->
<el-row >
<el-col :span="6">
<div class="grid-content1 bg-purple">第一列</div>
</el-col>
<el-col :span="6">
<div class="grid-content2 bg-purple-light">第二列</div>
</el-col>
<el-col :span="6">
<div class="grid-content1 bg-purple">第三列</div>
</el-col>
</el-row>
<!-- flex 布局 justify="center"居中 "start" "end" "space-between" -->
<el-row type="flex" justify="space-around">
<el-col :span="6">
<div class="grid-content1 bg-purple">flex 第一列</div>
</el-col>
<el-col :span="6"
><div class="grid-content2 bg-purple-light">flex 第二列</div>
</el-col>
<el-col :span="6"
><div class="grid-content1 bg-purple">flex 第三列</div>
</el-col>
</el-row>
-
响应式布局
参照了 Bootstrap 的 响应式设计,预设了五个响应尺寸:
xs
、sm
、md
、lg
和xl
。其实就是每行总共24个栅格,在不同尺寸的页面上如何分配宽度比例。
名称 尺寸 xs <768px sm ≥768px md ≥992px lg ≥1200px xl ≥1920px
<!-- 响应式布局 -->
<el-row :gutter="10">
<!-- 不同尺寸的页面时,跨的列数 -->
<el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1">
<div class="grid-content1 bg-purple">
第一列
</div>
</el-col>
<el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11">
<div class="grid-content2 bg-purple-light">
第二列
</div>
</el-col>
<el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11">
<div class="grid-content1 bg-purple">
第三列
</div>
</el-col>
<el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1">
<div class="grid-content2 bg-purple-light">
第四列
</div>
</el-col>
</el-row>
改变页面的尺寸,可以看出效果:
3.2 Container 布局容器
用于布局的容器组件,方便快速搭建整个页面
的基本结构:
<el-container>
:外层容器。当子元素中包含 <el-header>
或 <el-footer>
时,全部子元素会垂直上下排列,否则会水平左右排列。
<el-header>
:顶栏容器。
<el-aside>
:侧边栏容器。
<el-main>
:主要区域容器。
<el-footer>
:底栏容器。
以上组件采用了 flex 布局,使用前请确定目标浏览器是否兼容。此外,<el-container>
的子元素只能是后四者,后四者的父元素也只能是 <el-container>
。
4 element-ui常用组件
表格
当el-table
元素中绑定data
对象数组后,在el-table-column
中用prop
属性来对应对象中的键名即可填入数据,label
属性定义表格的列名,width
属性定义列宽。
<template>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [//一个对象代表一行数据
{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
}
}
</script>
分页
size-change
每页展示的数量改变时,触发
current-change
当前页码 变动时候触发的事件
page-sizes
可选择的页面展示数量,如[100, 200, 300, 400]
表示四个选项,每页显示 100 个,200 个,300 个或者 400 个。
page-size
当前 每页展示的数量
current-page
当前的页码
<template>
<div class="block">
<!--
@current-change 用户选择页面时 触发
@size-change 用户选择每页显示多少时,触发
current-page 当前页码,如 :current-page="3"
page-sizes 可选择的每页展示的数量
page-size 当前每页展示的数量,如 :page-sizes="[100, 200, 300]"
layout 分页的整体布局
total为分页的总数;
sizes可选择的页面展示数量;
prev 前一页;
pager 当前页;
next 下一页;
jumper 页面跳转;
total 总的分页数量
-->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[100, 200, 300, 400]"
:page-size="100"
layout="total, sizes, prev, pager, next, jumper"
:total="400">
</el-pagination>
</div>
</template>
<script>
export default {
methods: {
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`);
}
},
data() {
return {
currentPage: 4
};
}
}
</script>
导航菜单
<!-- 导航菜单 -->
<!--
el-menu, 菜单 , 默认垂直模式,通过mode='horizontal'改为水平模式
el-menu-item,菜单项
el-submenu,子菜单
el-menu-item-group 菜单项组
default-active 默认激活的选项, 如default-active="2"就是第二项默认激活
open 打开 子菜单 的事件
close 关闭 子菜单 的事件
background-color='#545c64' 整体菜单栏的背景色
text-color = '#fff' 字体颜色
active-text-color= "#ffd04b" 激活项 的文本颜色
-->
<el-row class="tac">
<el-col :span="6">
<h5>导航菜单</h5>
<el-menu
default-active="2"
@open="handleOpen"
@close="handleClose"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<!--菜单项1 是一个子菜单 index指定是第几项 -->
<el-submenu index="1">
<!-- template、div 均可以使用 -->
<div slot="title">
<!-- 前面加一个图标 -->
<i class="el-icon-location"></i><span>导航一</span>
</div>
<!-- 菜单项 第一组 -->
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="1-1">选项1</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
</el-menu-item-group>
<!-- 第二组 -->
<el-menu-item-group title="分组2">
<el-menu-item index="1-3">选项3</el-menu-item>
</el-menu-item-group>
<!-- 三级子菜单 -->
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项1</el-menu-item>
</el-submenu>
</el-submenu>
<!-- 菜单项2 -->
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
<!-- 菜单项3 不可点击-->
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span>导航三</span>
</el-menu-item>
<!-- 菜单项4 -->
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span>导航四</span>
</el-menu-item>
</el-menu>
</el-col>
</el-row>
methods:{
...
handleOpen(value){
console.log("打开子菜单", value)
},
handleClose(value){
console.log("关闭子菜单", value)
},
},
下拉菜单
<!-- 下拉菜单 dropdown -->
<el-dropdown @command="handleChange">
<span class="el-dropdown-link">
下拉菜单<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<!-- 下拉列表 -->
<el-dropdown-menu slot="dropdown">
<!-- 下拉列表项 -->
<el-dropdown-item command="1">黄金糕</el-dropdown-item>
<el-dropdown-item command="2">狮子头</el-dropdown-item>
<el-dropdown-item command="3">螺蛳粉</el-dropdown-item>
<el-dropdown-item command="4" disabled>双皮奶</el-dropdown-item>
<el-dropdown-item command="5" divided>蚵仔煎</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<style>
.el-dropdown-link {
cursor: pointer;
color: #409EFF;
}
.el-icon-arrow-down {
font-size: 12px;
}
</style>
树形控件
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick">
<!-- data 是一个数组 -->
</el-tree>
<script>
export default {
data() {
return {
data: [ //data 是一个数组 , 内部的每一个对象 是一个分支
{
label: '一级 1',
children: [
{
label: '二级 1-1',
children: [
{
label: '三级 1-1-1'
}
]
}
]
},
//第二个分支
{
label: '一级 2',
children: [
{
label: '二级 2-1',
children: [
{
label: '三级 2-1-1'
}
]
},
{
label: '二级 2-2',
children: [
{
label: '三级 2-2-1'
}
]
}
]
},
//第三个分支
{
label: '一级 3',
children: [
{
label: '二级 3-1',
children: [
{
label: '三级 3-1-1'
}
]
},
{
label: '二级 3-2',
children: [
{
label: '三级 3-2-1'
}
]
}
]
}
],
defaultProps: {
children: 'children',
label: 'label'
}
};
},
methods: {
handleNodeClick(data) {
console.log(data);
}
}
};
</script>
练习: 实现如下效果,
穿梭框
Transfer 的数据通过 data
属性传入。数据需要是一个对象数组,每个对象有以下属性:key
为数据的唯一性标识,label
为显示文本,disabled
表示该项数据是否禁止转移。目标列表中的数据项会同步到绑定至 v-model
的变量,值为数据项的 key
所组成的数组。当然,如果希望在初始状态时目标列表不为空,可以像本例一样为 v-model
绑定的变量赋予一个初始值。
<!-- 穿梭框 -->
<!--
v-model, 选中的项目,即放入右侧的项目(key 组成的数组)
data 所有的项目对象 数组,如[{key:1, label:"xxx"}]
button-texts 按钮文本 ['左边按钮', '右边按钮']
titles 左右两边的标题 ['待选择', '已选择']
filterable 可以搜索
target-order="push" 加入到右边的项目按照推入顺序排序,默认按照key排序
@change 左侧项目数 改变时触发, 传入value为已选中的项目(数组)
@right-check-change 右侧勾选改变时触发,传入的value为右侧勾选的项目(数组)
-->
<el-transfer
v-model="value"
:data="data1" :button-texts="['取消选择', '确定选择']"
:titles="['待选择', '已选择']"
:filterable="true"
target-order="push"
@change="leftChange"
@right-check-change="rightChange"
>
</el-transfer>
<script>
export default {
data() {
return {
data: generateData(),
value: [1, 4]
};
},
methods:{
generateData(){
const data = [];
for (let i = 1; i <= 15; i++) {
data.push({
key: i,
label: `备选项 ${ i }`,
// disabled: i % 4 === 0
});
}
return data;
},
},
};
</script>
日期选择器
基本单位由type
属性指定。快捷选项需配置picker-options
对象中的shortcuts
,禁用日期通过 disabledDate
设置
<template>
<div class="block">
<span class="demonstration">默认</span>
<el-date-picker
v-model="value1"
type="date"
placeholder="选择日期">
</el-date-picker>
</div>
</template>
以下为快捷方式,
快捷方式:选择时间
<el-date-picker v-model="value1" type="date" placeholder="选择日期"
:picker-options="pickerOptions" @change="handleDateChange">
</el-date-picker>
<script>
export default {
data(){
return {
pickerOptions: {
// 禁用是日期
disabledDate(time) { //time 为日历的时间对象
// 时间戳 大于当前时间是,设置为不可用
return time.getTime() > Date.now();
},
shortcuts: [
{ //快捷键
text: '今天',
onClick(picker) {
picker.$emit('pick', new Date());
}
},
// 快捷键
{
text: '昨天',
onClick(picker) {
// 创建日期对象
const date = new Date();
// 设置时间
date.setTime(date.getTime() - 3600 * 1000 * 24);
// 触发pick事件
picker.$emit('pick', date);
}
},
// 快捷键
{
text: '一周前',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', date);
}
}
]
},
value1: '', //绑定选中的日期
}
}
}
</script>
级联选择器
<!-- 级联选择器
options, 下拉选项
clearable, 是否可以清空
placeholder, 提示信息占位符
v-model 绑定选择的值
change 值改变的事件,可以接收当前改变的新值
-->
<el-cascader
:options="options"
:clearable="true"
placeholder="选择地区"
v-model="cascadeValue"
@change="handleCascaderChange">
</el-cascader>
<script>
export default {
data() {
return {
options: [
{
value: "zz", //一级选择
label: "郑州",
children: [
//二级选择
{
value: "z1",
label: "金水区",
},
{
value: "z2",
label: "二七区",
},
{
value: "z3",
label: "经开区",
},
],
},
// 一级选择
{
value: "sq",
label: "商丘",
children: [
{
value: "ycx",
label: "虞城县",
},
{
value: "xy",
label: "夏邑县",
},
{
value: "nl",
label: "宁陵",
},
],
},
// 一级选择
{
value: "xinxiang",
label: "新乡",
},
],
}
}
}
</script>
练习:设计实现如下级联选择器