在管理后台的项目中经常会出现这样的需求,表格数据的查询定位,表的上面是一个查询表单,下边是一张表。有时这种情况出现很多次,也有多次是重复的样式表单项,往往会重复做很多的工作,下面就是对这一部分的再度封住组件;
技术:vue.js ; elementUI
代码:
父组件调用该组件,先给组件取个合适的名称
<FormItem :formOptions="formOptions" @searchCallback="search"></FormItem>
要使上面的代码生效要引入组件和注册并且要设置好传给组件的表单信息以及获取组件返回的表单值的方法
import FormItem from '../../components/FormItem';
export default {
components: {
Dialog,
FormItem
},
data() {
return {
// 传给组件的表单信息
formOptions: [
{
// 表单项中文提示
label: '当前状态:',
// 表单项需要被绑定值的名称
name: 'status',
// 表单项的输入提示
placeholder: '请选择当前状态',
// 表单项是否可以清空操作 true为可,false为不可
clearable: true,
// 表单项是否有清空选项时的方法,这与clearable是对应的不能一个为false一个为true,
// true为有该方法,false为没有该方法
clearEventName: true,
// 表单项是否有值改变时触发的方法 true为有该方法,false为没有该方法
changeEventName: true,
// 表单项要用到的输入工具的名称
optionType: 'select',
// 如果是下拉选择的就有集合
selectList: [],
// 获取下拉集合的url
selectListUrl: '/oa/commonweal/get_location_photo_status.json',
// 下拉选项对应的value值的名称
valueName: 'status',
// 下拉选项对应的label的名称
labelName: 'status_desc',
},
{
label: '标题:',
name: 'photo_title',
placeholder: '请输入标题名称,可模糊搜索',
clearable: true,
clearEventName: 'resetPageCondition',
changeEventName: 'resetPageCondition',
optionType: 'input',
style: 'width: 300px;'
},
{
label: '计数器',
name: 'number',
placeholder: '',
changeEventName: 'resetPageCondition',
optionType: 'inputNumber',
min: 1,
max: 10
},
{
label: '时间选择器',
name: 'date',
placeholder: '请选择时间',
valueFormat: 'yyyy-MM-dd',
changeEventName: 'resetPageCondition',
optionType: 'datePicker',
dateType: 'daterange'
}
]
}
}
methods: {
search(formValue) {
// formValue是组件传来的表单的值
/*
这里就可以处理你想要的操作了,一般这里会做请求数据的操作,当然参数自然是formValue中各项的值了。
*/
}
}
}
下面最最主要的是组件的代码:
<template>
<div>
<el-form :inline="true" :model="formItem" ref="formItem">
<template v-for="(item, index) in formOptionsChild">
<el-form-item :label="item.label">
<template v-if="item.optionType == 'select'">
<el-select
v-model="formItem[item.name]"
:placeholder="item.placeholder"
:clearable="item.clearable"
@clear="handleItemEvent(item.clearEventName)"
@change="handleItemEvent(item.changeEventName)">
<el-option
v-if="item.selectList"
v-for="itemc in item.selectList"
:key="itemc[item.valueName]"
:label="itemc[item.labelName]"
:value="itemc[item.valueName]">
</el-option>
</el-select>
</template>
<template v-if="item.optionType == 'input'">
<el-input
v-model="formItem[item.name]"
:placeholder="item.placeholder"
:clearable="item.clearable"
@clear="handleItemEvent(item.clearEventName)"
:style="item.style">
</el-input>
</template>
<template v-if="item.optionType == 'inputNumber'">
<el-input-number
v-model="formItem[item.name]"
@change="handleItemEvent(item.changeEventName)"
:min="item.min ? Number(item.min) : 1"
:max="item.max ? Number(item.max) : 10"
label="描述文字">
</el-input-number>
</template>
<template v-if="item.optionType == 'datePicker'">
<el-date-picker
v-model="formItem[item.name]"
:type="item.dateType"
:placeholder="item.placeholder"
:value-format="item.valueFormat"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="handleItemEvent(item.changeEventName)">
</el-date-picker>
</template>
</el-form-item>
</template>
<el-form-item>
<el-button
type="primary"
:loading="loading"
icon="el-icon-search"
@click="searchCallback">
<span v-if="loading">查询中...</span>
<span v-else>查询</span>
</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
props: {
// 父组件中传递的表单的信息
formOptions: {
type: Array,
required: true,
default: function () {
return []
}
},
loading: {
type: Boolean,
required: true,
default: false
}
},
data() {
return {
// 用于存放响应式的表单项名称
formItem: {},
loading: false,
// 存放处理过后的表单信息
formOptionsChild: []
}
},
created() {
this.handleSelectList();
this.handleFormItemName();
},
methods: {
/**
* 处理表单项的名称
*/
handleFormItemName() {
if (this.formOptions.length) {
let items = this.formOptions;
items.forEach(item => {
// 绑定get和set,这样处理才能实现响应式
this.$set(this.formItem, item.name, '')
});
}
},
/**
* 处理下拉列表集合
*/
handleSelectList() {
if (this.formOptions.length) {
let items = this.formOptions;
this.formOptionsChild = items.map(item => {
if (item.selectListUrl) {
// 有些表单项是下拉集合的需要获取下拉集合项
// 通过axios来调用获取下拉集合的url
this.axios.get(item.selectListUrl, {}).then(res => {
if (res.retcode === 0) {
let result_rows = res.result_rows;
if (result_rows && result_rows instanceof Array && result_rows.length) {
item.selectList = result_rows;
} else {
item.selectList = [];
}
}
})
}
return item
})
}
},
/**
* 处理表单项的change或clear及其他方法
*/
handleItemEvent() {
// 向父组件传递改变的后form表单各项的值
this.$emit('searchCallback', this.formItem);
},
/**
* 点击查询回调
*/
searchCallback() {
// 向父组件传递改变的后form表单各项的值
this.$emit('searchCallback', this.formItem)
}
}
}
</script>
<style lang="scss">
</style>
组件可以根据想要的表单项目添加,没有固定灵活,每个表单项的形式也是可以灵活改变的