element适用于多个组件 input输入框组件的二次封装.
前言
用element的时候,经常需要写多个输入框,就想把它写成一个组件,看了网上很多例子,要么不符合我的要求,要么就是太复杂,所以想自己写一个对我来说比较通俗易懂的组件。有什么不妥的地方欢迎各位大佬指正
先上图片看看效果:有时间选择器,input输入框,下拉选择和按钮组 首先 首先使用了element的el-form表单组件,model是表单的数据对象,用于双向绑定;rules是表单的验证规则,inline是行内表单模式;关于更多详细参数,可参考官网element.eleme.cn/#/zh-CN/com…
关于输入框input 循环传过来的commodityMessage数组, 之前一直肯苦恼关于v-model绑定的字段必须是唯一的怎么整,后面为了方便就想到了,把循环的每个prop的字段名称和v-model绑定的ruleForm里面的字段名称保持一致就可以了。例如在data中这样:
ruleForm: {
number: "", //编号
orderNumber:"",//单号
},
commodityMessage: [
{
label: "编号",
prop: "number",
},
{
label: "单号",
prop: "orderNumber",
widths:'500'
},
我们得到的结果就是这样两个输入框,
关于Select 选择器
这部分我是判断在commodityMessage的每个对象中是否存在optionSelect对象,如果存在,就是select选择器,同样的v-model绑定的值是commodityMessage每个对象的prop的字段,我们相应的也要在ruleForm添加此字段。关于选择框的值是循环对象中的optionSelect,optionSelect中的label是绑定的是选择的label文字,optionSelect中的value是绑定的是选择得到的值 例如这样:
<el-select
v-else-if="item.optionSelect && !item.isDate"
v-model="ruleForm[item.prop]"
:placeholder="item.label ? '请输入'+ item.label : ''"
:style="item.widths ? 'width'+ item.widths +'%' : 'width:148px'"
>
<el-option
v-for="ele in item.optionSelect"
:key="ele.label"
:label="ele.label"
:value="ele.value"
></el-option>
</el-select>
ruleForm: {
site:"", //场地
},
commodityMessage: [
{
label: "场地",
prop: "site",
optionSelect: [
{
label: "全部",
value: "shanghai"
},
{
label: "零食区",
value: "beijing"
}
]
},
我们得到的结果是:
关于时间选择器
我们往往可能会需要用到时间选择器,所以我在这里也简单的写了一下 使用与input框的使用方法类似,只要在commodityMessage中的对象添加isDate:true就是时间选择器
ruleForm: {
startDate:'',
},
commodityMessage: [
{
label: "下单时间",
prop: "startDate",
isDate:true
},
我们可以看下效果:
关于按钮
在输入框中大多数都会使用到一些按钮,我在这里也简单封装了一下 循环searchBtns数组,name是按钮的文字,fun是按钮的函数名,type是按钮的颜色 然后在组件中分别绑定事件,字段名就是searchBtns的fun。例如:
<el-form-item v-if="searchBtns.length > 0 ">
<el-button size="mini" v-for="btn in searchBtns" :key="btn.name" @click="$emit(btn.fun)" :type="btn.type ? btn.type : 'primary'">{{btn.name}}</el-button>
</el-form-item>
使用中:
data(){
return{
searchBtns: [
{
name: "搜索",
fun:'onSearch'
},
{
name: "导出",
fun:'exportFun'
},
{
name: "清空搜索条件",
fun:'emptyFun',
type:'warning'
},
],
}
},
methods: {
onSearch(){
console.log('点击搜索按钮',this.ruleForm);
},
exportFun(){
console.log('导出');
},
emptyFun(){
console.log('清空搜索条件');
},
}
子组件源码:在components文件夹下创建一个search.vue
<template>
<div>
<!-- inline="true" 行内表单模式-->
<el-form
:model="ruleForm"
:rules="searchRules"
:inline="inline ? inline : false"
ref="ruleForm"
class="demo-ruleForm"
size="small"
>
<!-- label-width="80px" -->
<el-form-item
v-for="item in commodityMessage"
:key="item.prop"
:label="item.label ? item.label +':' : ''"
:prop="item.prop"
>
<el-input
v-if="!item.optionSelect && !item.isDate"
v-model="ruleForm[item.prop]"
:placeholder="item.label ? '请输入'+ item.label : ''"
:style="item.widths ? 'width'+ item.widths +'% !important;' : 'width:148px'"
>{{ item.prop }}</el-input
>
<el-select
v-else-if="item.optionSelect && !item.isDate"
v-model="ruleForm[item.prop]"
:placeholder="item.label ? '请输入'+ item.label : ''"
:style="item.widths ? 'width'+ item.widths +'%' : 'width:148px'"
>
<el-option
v-for="ele in item.optionSelect"
:key="ele.label"
:label="ele.label"
:value="ele.value"
></el-option>
</el-select>
<div v-else-if="item.isDate && !item.optionSelect ">
<div class="block" >
<!-- <span class="demonstration">{{item.label}}</span> -->
<el-date-picker
v-model="ruleForm[item.prop]"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</div>
</div>
</el-form-item>
<el-form-item v-if="searchBtns && searchBtns.length > 0 >
<el-button size="mini" v-for="btn in searchBtns" :key="btn.name" @click="$emit(btn.fun)" :type="btn.type ? btn.type : 'primary'">{{btn.name}}</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
props:{
inline: {
type: Boolean,
default: false
},
ruleForm: {
type: Object,
},
commodityMessage: {
type: Array,
},
searchRules: {
type: Object,
default() {
return {}
}
},
searchBtns: {
type: Array,
default() {
return []
}
},
operation: {
type: Object,
default() {
return {}
}
},
},
data() {
return {
activeSataus:0,
};
},
};
</script>
<style lang="scss" scoped>
.configurationTxt {
font-size: 14px;
padding-bottom: 10px;
}
.commodityMessageBox {
width: 100%;
display: flex;
flex-wrap: wrap;
.el-form-item {
width: 50%;
}
}
.Divline {
width: 100%;
border-bottom: 1px dashed #ddd;
margin: 20px 0;
}
.commodityEditBtnBox {
display: flex;
width: 100%;
justify-content: center;
align-items: center;
margin-top: 30px;
.el-button {
margin: 0 40px;
}
}
//
.el-form-item{
margin-right: 18px ;
}
//
.stateSpan{
font-weight: 700;
margin-right: 10px;
}
.stateBtnBox{
display: inline-block;
margin-right: 10px;
}
</style>
父组件使用
<template>
<div class="setBg">
<ele-search
:inline="true"
:ruleForm="ruleForm"
:commodityMessage="commodityMessage"
:searchRules="searchRules"
:searchBtns="searchBtns"
@onSearch="onSearch"
@exportFun="exportFun"
@emptyFun="emptyFun"
/>
</div>
</template>
<script>
import eleSearch from "../../components/eleSearch";
export default {
components: { eleSearch },
data() {
return {
ruleForm: { // v-model绑定
site:"", //场地
number: "", //编号
orderNumber:"",//单号
orderType: "", //订单状态
startDate:'',
},
commodityMessage: [ //
{
label: "下单时间",
prop: "startDate",
isDate:true
},
{
label: "场地",
prop: "site",
optionSelect: [
{
label: "全部",
value: "shanghai"
},
{
label: "零食区",
value: "beijing"
}
]
},
{
label: "编号",
prop: "number",
},
{
label: "单号",
prop: "orderNumber",
widths:'500'
},
{
label: "订单状态",
prop: "orderType",
optionSelect: [
{
label: "全部",
value: "shanghai"
},
{
label: "待支付",
value: "zhifu"
},
{
label: "已支付",
value: "yizhifu"
},
{
label: "已退款",
value: "yituikuan"
}
]
},
],
searchRules: { // 校验
orderNumber: [
{ required: true, message: "请输入单号", trigger: "blur" },
{ min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" }
],
number: [
{ min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" }
],
},
searchBtns: [ // 按钮们
{
name: "搜索",
fun:'onSearch'
},
{
name: "导出",
fun:'exportFun'
},
{
name: "清空搜索条件",
fun:'emptyFun',
type:'warning'
},
],
};
},
methods: {
onSearch(){
console.log('点击搜索按钮',this.ruleForm);
},
exportFun(){
console.log('导出');
},
emptyFun(){
console.log('清空搜索条件');
},
}
};
</script>
<style lang="scss" scoped>
</style>