在我们使用Vue+Element开发前端的时候,往往涉及到很多界面组件的使用,其中很多直接采用Element官方的案例即可,有些则是在这个基础上封装更好利用、更少代码的组件;另外有些则是直接采用第三方开发好的组件,目的就是实现所需功能外,尽量简化界面使用代码。本篇随笔介绍在我的项目中经常用到的各种界面组件和它的界面效果,以便在实际开发中进行相应的参考,提高开发效率。
我们以几个常规界面来介绍相关控件的使用,如列表界面,包括查询、表格、分页等信息,查询框中包含一些关键字段的信息查询,而表格中则包含重要字段信息的展示或者相关操作。
然后编辑界面,简单的如下所示。
复杂界面中,包含很多录入信息的界面组件
另外还可以设计富文本、图片上传等操作。
以上就是一些常规界面的录入情况,其中使用到了很多相关的界面组件,包括文本录入框、下拉选框、树列表、标签、图片上传、富文本、日期、省市区列表等等。
下面分别对一些常规的界面组件的使用进行介绍。
1、普通文本输入框
文本框一般是比较常见的界面组件,一个是内容录入比较灵活,其次也是因为使用简单方便。
一般这种录入界面组件,都是放在表单里面处理比较多,因为可以利用表单的校验功能实现校验等操作,也可以利用表单对应的对象属性一并提交。
使用代码很简单,如下所示。
<el-form-item label="姓名" prop="name"> <el-input v-model="searchForm.name" /> </el-form-item>
如果是有些录入需要有前缀或者后缀的,则可以通过Slot模板进行处理。
<el-col :span="12"> <el-form-item label="身高" prop="height"> <el-input v-model="addForm.height"><span slot="suffix">厘米</span></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="体重" prop="weight"> <el-input v-model="addForm.weight"><span slot="suffix">公斤</span></el-input> </el-form-item> </el-col>
或者我们参考官方Element的案例,也可以看到使用的效果和代码
<div> <el-input placeholder="请输入内容" v-model="input1"> <template slot="prepend">Http://</template> </el-input> </div> <div style="margin-top: 15px;"> <el-input placeholder="请输入内容" v-model="input2"> <template slot="append">.com</template> </el-input> </div> <div style="margin-top: 15px;"> <el-input placeholder="请输入内容" v-model="input3" class="input-with-select"> <el-select v-model="select" slot="prepend" placeholder="请选择"> <el-option label="餐厅名" value="1"></el-option> <el-option label="订单号" value="2"></el-option> <el-option label="用户电话" value="3"></el-option> </el-select> <el-button slot="append" icon="el-icon-search"></el-button> </el-input> </div>
另外,文本输入框还包括一个多行的输入textarea的类型输入。
<el-input type="textarea" placeholder="请输入内容" v-model="textarea" maxlength="30" show-word-limit>
有时候,文本框还需要输入长度的限制,这个在文本框很容易设置,界面效果如下所示。
界面代码如下所示。
<el-input type="text" placeholder="请输入内容" v-model="text" maxlength="10" show-word-limit> </el-input> <div style="margin: 20px 0;"></div> <el-input type="textarea" placeholder="请输入内容" v-model="textarea" maxlength="30" show-word-limit> </el-input>
2、日期输入范围选择
日期我们一般用内置的el-date-picker即可,可以显示短日期、带时间的长日期,或者选择日期范围多项选择。
<el-form-item label="出生日期" prop="birthDate"> <el-date-picker v-model="addForm.birthDate" align="right" type="date" placeholder="选择日期" value-format="yyyy-MM-dd" /> </el-form-item>
而我们在查询的时候,一般就是一个日期区间。
我们只需要指定type="daterange"即可。
<el-form-item label="创建时间"> <el-date-picker v-model="searchForm.creationTime" type="daterange" align="right" unlink-panels range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" :picker-options="pickerOptions" /> </el-form-item>
其中的 pickerOptions 则是我们定义的快捷选择项,单独放置一个文件constantOptions.js里面,需要导入对象使用即可,这样可以减少很多页面的JS代码,其他常见变量也是这样的方式处理。
// 选择时间范围的快捷选项 export const pickerOptions = { shortcuts: [ { text: '昨天', onClick(picker) { const end = new Date(); const start = new Date(); start.setTime(start.getTime() - 3600 * 1000 * 24 * 1); picker.$emit('pick', [start, end]); } }, { text: '最近一周', onClick(picker) { const end = new Date(); const start = new Date(); start.setTime(start.getTime() - 3600 * 1000 * 24 * 7); picker.$emit('pick', [start, end]); } }, { text: '最近一个月', onClick(picker) { const end = new Date(); const start = new Date(); start.setTime(start.getTime() - 3600 * 1000 * 24 * 30); picker.$emit('pick', [start, end]); } }, { text: '最近三个月', onClick(picker) { const end = new Date(); const start = new Date(); start.setTime(start.getTime() - 3600 * 1000 * 24 * 90); picker.$emit('pick', [start, end]); } }] }
日期输入控件,有时候会出现获得的日期值比实际的值少一天的问题,一般通过设置 value-format="yyyy-MM-dd" 即可解决。
3、标签显示和录入
标签的显示和录入,也是我们很常见的处理,多颜色的标签可以提高界面的美观,同时也是对多选值的友好显示。
我们先来看看官方的案例。
<el-tag>标签一</el-tag> <el-tag type="success">标签二</el-tag> <el-tag type="info">标签三</el-tag> <el-tag type="warning">标签四</el-tag> <el-tag type="danger">标签五</el-tag>
其实就是指定type不同就可以实现不同的效果,另外我们还可以通过设置effect属性来改变主题,默认为 light
标签的显示是有了,一般我们还需要一个标签的录入操作,虽然官方也提供了一个案例,不过是简单对Tag标签组件的使用,代码还是不少。
实际上,我们在使用组件的时候,系统尽量减少代码量,因此我们可以参考官方的方式建立一个集标签显示和录入功能一起的组件,不过Github上已经有人开发了,我就直接拿过来用吧。
https://github.com/xiispace/el-input-tag
界面效果如下所示。
使用的时候,界面代码和普通组件一样简单,非常棒。
<el-form-item label="标签" prop="tags"> <el-input-tag v-model="editForm.tags_array" /> </el-form-item>
JS部分只需要转换下我们的内容即可。我们tags属性存储是逗号分开的字符串,那么tags_array这是数组,我们获取值的时候,需要进行转换,把字符串转换为数组的值。
// 将字符串的标签,转换为Array集合 if (this.addForm.tags) { this.addForm.tags_array = this.addForm.tags.split(',') }
而修改组件,会引起数组的改变,为了避免集中转换,我们可以通过watch函数来统一处理,这样tags内容就会自动变化了。
watch: { // 对过滤内容进行监控,实现树列表过滤 // 键路径必须加上引号 'addForm.tags_array': function(val, oldval) { if (val) { this.addForm.tags = val.toString() } }, 'editForm.tags_array': function(val, oldval) { if (val) { this.editForm.tags = val.toString() } } },
4、下拉列表和字典列表Select组件
下拉列表或者下拉框是我们常见的选择方式之一,下拉列表有时候可以是固定列表,如男女、有效/无效, 也可以是多个动态列表供选择。
或者
或者是一连串联动的组件构成。
Select组件的使用如下所示。
<el-select v-model="value" placeholder="请选择"> <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select>
而其中的JS部分,options就是有value,lable组成的对象数组,如下代码所示
<script> export default { data() { return { options: [{ value: '选项1', label: '黄金糕' }, { value: '选项2', label: '双皮奶' }], value: '' } } } </script>
为el-select
设置clearable
属性,则可将选择器清空。为el-select
添加filterable
属性即可启用搜索功能。
为el-select
设置multiple
属性即可启用多选,此时v-model
的值为当前选中值所组成的数组。默认情况下选中值会以 Tag 的形式展现,你也可以设置collapse-tags
属性将它们合并为一段文字。
纵观Select组件,其数据源要么是固定列表,要么是从数据库字典里面获取的内容,为了简化界面代码的调用,我们把它作为字典组件进行了定义,可以绑定固定列表,也可以绑定字典表里面的字典类型名称。
组件使用很简单,如下代码所示。
<el-form-item label="状态"> <my-dictdata v-model="addForm.status" :options="Status"/> <my-dictdata v-model="addForm.status" type-name="状态"/> </el-form-item>
创建一个组件,定义好两个属性,如下代码所示。
在组件Mounted的时候,我们对这些内容进行解析,构建为对应组件的数据源即可。
mounted() { var that = this; if (this.typeName && this.typeName !== '') { // 使用字典类型,从服务器请求数据 var params = { dictTypeName: this.typeName }; dictdata.GetListItemByDictType(params).then(data => { var list = data.result; // console.log(list); if (list) { list.forEach(item => { // console.log(item) that.dictItems.push({ text: item.text, value: item.value }); }) } }) } else if (this.options && this.options.length > 0) { // 使用固定字典列表 this.options.forEach(item => { if (item && typeof (item.value) !== 'undefined') { that.dictItems.push(item) } }); } // 设置默认值 this.svalue = this.value; },
这样,使用起来就很方便了,可以直接绑定字典类型即可。
<el-col :span="12"> <el-form-item label="民族" prop="nationality"> <my-dictdata v-model="editForm.nationality" type-name="民族" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="学历" prop="education"> <my-dictdata v-model="editForm.education" type-name="学历" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="婚姻状况" prop="marriage"> <my-dictdata v-model="editForm.marriage" type-name="婚姻状况" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="星座" prop="star"> <my-dictdata v-model="editForm.star" type-name="星座" /> </el-form-item> </el-col>
这样的组件,相对于每次调用API去获取字典资源,然后进行转换处理,代码更加简单易懂了,同时也更加优雅,提高代码质量。
5、复选框和单选框
复选框和单选框也是经常使用的,对简单的一些选项进行勾选处理。
多选框有多选框组,单选框也有单选框组,这样组合起来界面更加美观。
<template> <el-checkbox-group v-model="checkList"> <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> </template> <script> export default { data () { return { checkList: ['选中且禁用','复选框 A'] }; } }; </script>
<template> <el-radio-group v-model="radio"> <el-radio :label="3">备选项</el-radio> <el-radio :label="6">备选项</el-radio> <el-radio :label="9">备选项</el-radio> </el-radio-group> </template> <script> export default { data () { return { radio: 3 }; } } </script>
这两个是官方比较典型的案例说明了,一般我们也是以组合的方式进行使用。
例如我们在产品类型绑定品牌列表的时候,就是采用了复选框汉族,通过key/value的集合组合即可实现键值对的处理。
<el-col :span="24"> <el-form-item label="品牌关联" prop="bindBrands"> <el-checkbox-group v-model="addForm.bindBrands" style="padding:10px;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1)"> <el-checkbox v-for="(item, i) in brandList" :key="i" :label="item.id">{{ item.brandName }}</el-checkbox> </el-checkbox-group> </el-form-item> </el-col>
<el-form-item label="虚拟商品" prop="isVirtual"> <el-radio-group v-model="addForm.isVirtual"> <el-radio class="radio" :label="1">是</el-radio> <el-radio class="radio" :label="0">否</el-radio> </el-radio-group> </el-form-item>
5、Switch开关
Switch开关有点类似于单选框的操作,不过提供比较美观的一个处理,表示两种相互对立的状态间的切换,多用于触发「开/关」。
<el-switch v-model="value1" active-text="按月付费" inactive-text="按年付费"> </el-switch> <el-switch style="display: block" v-model="value2" active-color="#13ce66" inactive-color="#ff4949" active-text="按月付费" inactive-text="按年付费"> </el-switch> <script> export default { data() { return { value1: true, value2: true } } }; </script>
这个组件提供了很多属性配置,可以自定义激活/未激活的颜色、文本、值的信息,如下说明。
因此,我们有时候的值如果是0,1的就可以设置一下active-value/inactive-value的值,否则默认是Boolean变量。
如下,有时候我们在查询中也会增加一个Switch来处理一些属性查询。
如果我们这样用,而isVirtual属性是0,1的数值的话,那么我们就需要进行转换了
<el-form-item label="虚拟商品" prop="isVirtual"> <el-switch v-model="searchForm.isVirtual" active-color="#13ce66" inactive-color="gray" /> </el-form-item>
那么我们发起查询的时候,就需要把布尔变量转换为0,1的值了,如下代码所示
getlist() { // 列表数据获取 var param = { // 构造常规的分页查询条件 // 分页条件 SkipCount: (this.pageinfo.pageindex - 1) * this.pageinfo.pagesize, MaxResultCount: this.pageinfo.pagesize, // 查询过滤条件 Code: this.searchForm.code, Name: this.searchForm.name, IsVirtual: this.searchForm.isVirtual }; // 使用日期范围选择控件,在查询对象增加开始日期CreationTimeStart、结束日期CreationTimeEnd this.addDateRange(param, this.searchForm.creationTime) param.IsVirtual = param.IsVirtual ? 1 : 0;// 修改数据类型为int // console.log(param) // 获取列表,绑定到模型上,并修改分页数量 this.listLoading = true productType.GetAll(param).then(data => { this.list = data.result.items this.pageinfo.total = data.result.totalCount this.listLoading = false }) },
或者我们定义active-value、inactive-value来处理会简单一些。
<el-form-item label="虚拟商品" prop="isVirtual"> <el-switch v-model="searchForm.isVirtual" active-value="1" inactive-value="0" active-color="#13ce66" inactive-color="gray" /> </el-form-item>
那这样查询就不需要转换bool到数值了,因为已经默认是0/1的数值类型了,更改后的查询代码如下所示。
getlist() { // 列表数据获取 var param = { // 构造常规的分页查询条件 // 分页条件 SkipCount: (this.pageinfo.pageindex - 1) * this.pageinfo.pagesize, MaxResultCount: this.pageinfo.pagesize, // 查询过滤条件 Code: this.searchForm.code, Name: this.searchForm.name, IsVirtual: this.searchForm.isVirtual }; // 使用日期范围选择控件,在查询对象增加开始日期CreationTimeStart、结束日期CreationTimeEnd this.addDateRange(param, this.searchForm.creationTime) // console.log(param) // 获取列表,绑定到模型上,并修改分页数量 this.listLoading = true productType.GetAll(param).then(data => { this.list = data.result.items this.pageinfo.total = data.result.totalCount this.listLoading = false }) },
6、消息提示及弹框
在组件或者页面里面,我们都需要大量使用到提示信息,确认信息等信息提示功能。而Element也提供了这样不同的组件来使用。
多个不同类型的消息提示窗口,界面如下所示。
Notification 通知组件,悬浮出现在页面角落,显示全局的通知提醒消息。界面如下所示
我们为了方便,一般先简单封装一下,并在全局挂载这些方法,以便在不同的地方简化调用。
// 提示成功信息 Vue.prototype.msgSuccess = function(msg) { this.$message({ showClose: true, message: msg, type: 'success' }) } // 提示警告信息 Vue.prototype.msgWarning = function(msg) { this.$message({ showClose: true, message: msg, type: 'warning' }) } // 提示错误信息 Vue.prototype.msgError = function(msg) { this.$message({ showClose: true, message: msg, type: 'error' }) } // 提示信息 Vue.prototype.msgInfo = function(msg) { this.$message.info({ showClose: true, message: msg }) } // 确认信息 Vue.prototype.msgConfirm = function(msg = '您确认删除选定的记录吗?') { return this.$confirm(msg, '操作提示', { type: 'warning' // success,error,info,warning // confirmButtonText: '确定', // cancelButtonText: '取消' }) }
这样我们在页面中就可以很方便使用了,如删除确认对话框操作。
showDelete(id) { // 删除对话框处理 this.msgConfirm().then(() => { // 删除操作处理代码 var param = { id: id } productType.Delete(param).then(data => { // console.log(data) if (data.success) { // 提示信息 this.msgSuccess('删除成功!') // 刷新数据 this.getlist() } else { this.msgError('删除失败:' + data.error) } }) }) },
由于篇幅有限,下篇在继续介绍其他组件的使用了。
为了方便读者理解,我列出一下前面几篇随笔的连接,供参考:
循序渐进VUE+Element 前端应用开发(1)--- 开发环境的准备工作
循序渐进VUE+Element 前端应用开发(2)--- Vuex中的API、Store和View的使用
循序渐进VUE+Element 前端应用开发(3)--- 动态菜单和路由的关联处理
循序渐进VUE+Element 前端应用开发(4)--- 获取后端数据及产品信息页面的处理
循序渐进VUE+Element 前端应用开发(5)--- 表格列表页面的查询,列表展示和字段转义处理
循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用
循序渐进VUE+Element 前端应用开发(7)--- 介绍一些常规的JS处理函数
循序渐进VUE+Element 前端应用开发(8)--- 树列表组件的使用
循序渐进VUE+Element 前端应用开发(9)--- 界面语言国际化的处理
循序渐进VUE+Element 前端应用开发(10)--- 基于vue-echarts处理各种图表展示
循序渐进VUE+Element 前端应用开发(11)--- 图标的维护和使用
循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理
循序渐进VUE+Element 前端应用开发(13)--- 前端API接口的封装处理
循序渐进VUE+Element 前端应用开发(14)--- 根据ABP后端接口实现前端界面展示
循序渐进VUE+Element 前端应用开发(15)--- 用户管理模块的处理
循序渐进VUE+Element 前端应用开发(16)--- 组织机构和角色管理模块的处理
循序渐进VUE+Element 前端应用开发(17)--- 菜单管理
循序渐进VUE+Element 前端应用开发(18)--- 功能点管理及权限控制
循序渐进VUE+Element 前端应用开发(19)--- 后端查询接口和Vue前端的整合
循序渐进VUE+Element 前端应用开发(20)--- 使用组件封装简化界面代码
循序渐进VUE+Element 前端应用开发(21)--- 省市区县联动处理的组件使用
循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中
循序渐进VUE+Element 前端应用开发(23)--- 基于ABP实现前后端的附件上传,图片或者附件展示管理