1. 创建一个searchForm
组件,将需要封装的searchForm
组件全局注册,为了方便下次直接使用
在main.js
文件中全局注册
import SearchForm from './components/SearchForm'
Vue.component('SearchForm', SearchForm)
2. 在searchForm
组件中创建基本结构
<template>
<div class="ces-search">
<el-form
class="form"
ref="refForm"
:size="size"
inline
:label-width="labelWidth"
>
<el-form-item
v-for="item in searchForm"
:label="item.label"
:key="item.prop"
class="formItem"
>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: "SearchForm",
props: {
//控制文本框大小
labelWidth: {
type: String,
default: "50px",
},
//控制每个控件的尺寸
size: {
type: String,
default: "mini",
},
//渲染表单的表头和类型的数据
searchForm: {
type: Array,
default: () => [],
},
//表单收集到的值
searchData: {
type: Object,
default: () => {},
},
},
data() {
return {};
},
methods: {},
};
</script>
<style lang="less" >
.ces-search {
display: flex;
justify-content: space-between;
.formItem {
.el-form-item__label {
width: 80px !important;
}
}
}
</style>
以上通过props传递的数据包含业务相关数据
,组件前端行为需要的数据
el-form-item
会根据传递的searchForm
数据进行遍历,每遍历一次会产生一个el-form-item
,而我们只需要在遍历时拿着每一项进行判断,进而创建对应的表单组件
<el-form-item
v-for="item in searchForm"
:label="item.label"
:key="item.prop"
class="formItem"
>
<!-- 输入框 -->
<el-input
v-if="item.type === 'Input'"
v-model="searchData[item.prop]"
size="mini"
:style="{ width: item.width }"
>
</el-input>
<!-- 下拉框 -->
<el-select
v-if="item.type === 'Select'"
v-model="searchData[item.prop]"
size="mini"
@change="item.change(searchData[item.prop])"
:style="{ width: item.width }"
>
<el-option
v-for="op in item.options"
:label="op.label"
:value="op.value"
:key="op.value"
>
</el-option>
...
...
...
</el-form-item>
3. 使用searchForm
组件,并通过props传递数据
<template>
<div class="ces-main">
<searchForm
label-width="50px"
:searchData="searchData"
:searchForm="searchForm"
>
</searchForm>
</div>
</template>
export default {
name: "home",
data() {
//表单查询一般分为input,下拉框,和日期,下面是下拉框时的设置下拉信息的情况,我的项目没有用到,但是留着方便看
let sexs = [
{ label: "男", value: "1" },
{ label: "女", value: "2" },
];
let sexProps = { label: "label", value: "value" };
return {
searchData: {
//查询表单的对应的值
name: "",
sex: null,
},
searchForm: [
//这里是渲染查询表单的表头和类型的数据
{
type: "Input",
label: "姓名",
prop: "name",
width: "180px",
placeholder: "请输入姓名...",
},
{
type: "Select",
label: "性别",
prop: "sex",
width: "180px",
options: sexs,
props: sexProps,
change: (row) => console.log(row),
placeholder: "请选择性别...",
},
],
};
},
};
</script>
4. 表单操作按钮=>查询、新增、删除等按钮
给searchForm
组件通过props
传递一个:isHandle="true"
属性用来控制是否展示查询按钮等内容
<searchForm
:isHandle="true"
size="mini"
label-width="50px"
:searchData="searchData"
:searchForm="searchForm"
:searchHandle="searchHandle"
>
</searchForm>
在searchForm
组件声明props
属性接收
export default {
props: {
isHandle: {
type: Boolean,
default: true, //默认为true,展示
},
...
在模板中使用v-if
判断isHandle
属性,为true展示否则隐藏
在通过props
传递一个searchHandle
进行遍历展示具体内容
searchHandle: [
{ label: "查询", type: "primary", handle: this.handleQuery },
{ label: "重置", type: "primary", handle: this.handleReset },
],
在子组件声明接收
export default {
props: {
isHandle: {
type: Boolean,
default: true, //默认为true,展示
},
searchHandle: {
type: Array,
default: () => [],
},
...
...
...
接收完之后在子组件遍历展示
<el-form class="formT" inline v-if="isHandle">
<el-form-item v-for="(item, index) in searchHandle" :key="index">
<el-button
:type="item.type"
:size="item.size || size"
@click="item.handle(12)"
>{{ item.label }}</el-button
>
</el-form-item>
</el-form>
5. 效果图展示:
6. 总结
在searchForm
中配置一组组对象,对象中包含要生成的控件类型并且添加一个属性,该属性的名字和在父组件的data
定义的名字同名,因为要保证收集到的数据是响应式的,然后将该对象通过props传递给searchForm
组件,之后会对searchForm
进行遍历,每遍历一次就会根据当前对象生成一个表单控件