由于elementui的el-select里是通过el-option遍历实现的,而遍历数组options按elementui官方不是绑定在el-select上的,所以针对el-select的配置项再加一个options里属性,即select选择项的数据数组。
<el-select v-if="isSelect" v-model="currentVal" v-bind="bindProps" v-on="bindEvents" size="mini" clearable > <el-option v-for="item in itemOptions.options" :key="item.value" :label="item.label" :value="item.value" ></el-option> </el-select>
elementui的日期时间选择器分了很多种,根据业务需要分别处理一下,我这里是根据type划分成了三种分开处理,最常用的是datetimerange日期时间范围选择器,作为默认项,还有一种monthrange,其余的都划为一种。(具体处理见文章末尾的完整代码)
6、按钮组
按钮其实就那么几个,没必要做太多的封装,根据业务有哪些按钮就封装进去,目前我这里就封装了三个按钮。
通过props接受一个字符串标识按钮组:
// 提交按钮项,多个用逗号分隔(query搜索, export导出, reset重置) btnItems: { type: String, default () { return 'search' } }
7、使用方式示例
dom:
<!-- 搜索 --> <searchForm :formOptions="formOptions" @onSearch="onSearch"/>
vue data里:
formOptions: [ { label: '意见内容', prop: 'content', element: 'el-input' }, { label: '类型', prop: 'type', element: 'el-select', options: [ { label: '给点意见', value: '1' }, { label: '售后问题', value: '2' } ] }, { label: '状态', prop: 'status', element: 'el-select', options: getFeedbackStatus() }, { label: '提交时间', prop: 'timeRange', element: 'el-date-picker' } ],
vue methods里:
// 获取搜索表单提交的数据 onSearch (val) { console.log(val) }
8、完整代码
(1)searchForm.vue
/** * Created by hanxueqiang on 200107 * * 搜索栏公共组件 */ <template> <div> <el-form :model="formData" ref="formRef" :inline="true" > <el-form-item v-for="(item, index) in formOptions" :key="newKeys[index]" :prop="item.prop" :label="item.label ? (item.label + ':') : ''" :rules="item.rules" > <formItem v-model="formData[item.prop]" :itemOptions="item" /> </el-form-item> </el-form> <!-- 提交按钮 --> <div> <el-button v-if="btnItems.includes('search')" size="mini" type="primary" @click="onSearch" >搜索</el-button> <el-button v-if="btnItems.includes('export')" size="mini" type="primary" @click="onExport" >导出</el-button> <el-button v-if="btnItems.includes('reset')" size="mini" type="default" @click="onReset" >重置</el-button> </div> </div> </template> <script> import formItem from './formItem' import tools from '@/utils/tools' export default { props: { /** * 表单配置 * 示例: * [{ * label: '用户名', // label文字 * prop: 'username', // 字段名 * element: 'el-input', // 指定elementui组件 * initValue: '阿黄', // 字段初始值 * placeholder: '请输入用户名', // elementui组件属性 * rules: [{ required: true, message: '必填项', trigger: 'blur' }], // elementui组件属性 * events: { // elementui组件方法 * input (val) { * console.log(val) * }, * ...... // 可添加任意elementui组件支持的方法 * } * ...... // 可添加任意elementui组件支持的属性 * }] */ formOptions: { type: Array, required: true, default () { return [] } }, // 提交按钮项,多个用逗号分隔(query, export, reset) btnItems: { type: String, default () { return 'search' } } }, data () { return { formData: {} } }, computed: { newKeys () { return this.formOptions.map(v => { return tools.createUniqueString() }) } }, created () { this.addInitValue() }, methods: { // 校验 onValidate (callback) { this.$refs.formRef.validate(valid => { if (valid) { console.log('提交成功') console.log(this.formData) callback() } }) }, // 搜索 onSearch () { this.onValidate(() => { this.$emit('onSearch', this.formData) }) }, // 导出 onExport () { this.onValidate(() => { this.$emit('onExport', this.formData) }) }, onReset () { this.$refs.formRef.resetFields() }, // 添加初始值 addInitValue () { const obj = {} this.formOptions.forEach(v => { if (v.initValue !== undefined) { obj[v.prop] = v.initValue } }) this.formData = obj } }, components: { formItem } } </script> <style lang='less' scoped> .search-form-box { display: flex; margin-bottom: 15px; .btn-box { padding-top: 5px; display: flex; button { height: 28px; } } .el-form { /deep/ .el-form-item__label { padding-right: 0; } .el-form-item { margin-bottom: 0; &.is-error { margin-bottom: 22px; } } // el-input宽度 /deep/ .form-item { > .el-input:not(.el-date-editor) { width: 120px; } } /deep/ .el-select { width: 120px; } /deep/ .el-cascader { width: 200px; } } } </style>
(2)formItem.vue