很早之前就使用过Vue的动态组件标签component实现功能模块自定义排序功能,这次使用Element组件库实现表单搜索通用组件
这里我主要拿三个常用的组件举例,输入框(Input)、选择框(Select)以及时间选择器DatePicker
- 话不多说,我们首先创建一个组件search-form
<template>
<div class="search-form-wrapper">
</div>
</template>
<script>
export default {
name: "searchForm"
}
</script>
<style scoped>
</style>
- 引入Element的Input、Select和DatePicker
import { Input, Select, DatePicker } from 'element-ui'
- 定义可绑定的组件类型数组。只需要传type类型进来,绑定对应的组件就行了
props: {
queryList: {
type: Array,
require: true,
default: []
}
},
data() {
return {
componentList: [
{ type: 'input', component: Input },
{ type: 'select', component: Select },
{ type: 'datePicker', component: DatePicker }
]
}
},
- 循环渲染需要动态绑定的表单数组
<div class="search-item" v-for="(item, index) in queryList" :key="item.id + '_query_' + index">
<div class="search-label">{{item.label}}</div>
<div class="search-inner">
<component
clearable
size="small" // 组件尺寸
:style="item.style ? item.style : 'width: 240px;'"
:id="item.id"
:name="item.name"
v-bind:is="componentList.filter(it => {return it.type === item.type})[0].component" // 根据type类型绑定对应组件
:placeholder="item.tips" // placeholder
v-model="item.value"
:value-format="item.format" // DatePicker format
:type="item.dateType" // DatePicker type
:range-separator="item.separator"
:start-placeholder="item.startPlaceholder" // DatePicker 范围开始placeholder
:end-placeholder="item.endPlaceholder" // DatePicker 范围结束placeholder
:default-time="item.defaultTime" // DatePicker 时间默认值
>
<el-option v-if="item.type === 'select'" v-for="(it, ind) in item.options"
:key="item.id + '_option_' + it.value" :label="it.label" :value="it.value"></el-option>
</component>
</div>
</div>
- 需要添加”搜索”和”重置”按钮
<el-button style="margin-bottom: 12px;" type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button style="margin-bottom: 12px;" icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
js部分:
methods: {
handleQuery: function() {
this.$emit("handleQuery");
},
resetQuery: function() {
this.$emit("resetQuery");
}
}
- 组件代码基本编写完毕,接下来就是应用了,引入组件,绑定需要动态绑定的数组
<template>
<div class="home">
<search-form :query-list="queryList" @handleQuery="handleQuery" @resetQuery="resetQuery"></search-form>
</div>
</template>
<script>
import SearchForm from "../components/search-form";
export default {
name: 'Home',
components: {
SearchForm
},
data() {
return {
queryList: [
{
id: "machineId",
name: "machineId",
label: "设备ID",
tips: "请输入设备ID",
type: "input",
value: "",
},
{
id: "category",
name: "category",
label: "设备类型",
tips: "请选择设备类型",
type: "select",
value: "",
options: [
{label: "CNC", value: "CNC"},
{label: "IMM", value: "IMM"}
],
},
{
id: "createDateRange",
name: "createDateRange",
label: "创建时间",
type: "datePicker",
format: "yyyy-MM-dd HH:mm:ss",
separator: "-",
dateType: "datetimerange",
style: "width: 340px",
startPlaceholder: "开始",
endPlaceholder: "结束",
value: "",
propName: ["createDateStart", "createDateEnd"],
defaultTime: ["00:00:00", "23:59:59"]
},
],
}
},
methods: {
handleQuery: function () {
},
resetQuery: function () {
}
}
}
</script>
实现后的效果:
- 重置方法,我们只需要清空绑定数组的value
this.queryList.forEach((item) => {
item.value = "";
});
- 查询方法,我们最后调用接口需要的格式是{name: value}
/** 列表请求参数对象构造 */
export function buildSearchQuery(array) {
let obj = {}
array.forEach(item => {
if (null !== item.value && '' !== item.value) {
if (item.type === 'datePicker') {
if (item.dateType === "date") {
obj[item.id] = item.value;
} else {
if (null !== item.value && '' !== item.value) {
if (item.propName) {
obj[item.propName[0]] = item.value[0];
obj[item.propName[1]] = item.value[1];
} else {
obj['beginTime'] = item.value[0];
obj['endTime'] = item.value[1];
}
}
}
} else {
obj[item.id] = item.value
}
}
})
return obj
}