Element is suitable for secondary encapsulation of multiple component input box components.

preface

When I used Element, I often needed to write multiple input fields, so I wanted to write it as a component. I saw many examples on the Internet, but either they didn’t meet my requirements or they were too complicated, so I wanted to write a component that was easier for me to understand. Welcome to point out what is wrong with you

Let’s start with the image to see what it looks like: time picker, input field, drop-down selection and button group First of all,First, element’s el-Form component is used. Model is the data object of the form and is used for bidirectional binding. Rules is the validation rule for a form, inline is the inline form mode. For more detailed parameters, please refer to the official websiteElement. The eleme. Cn / # / useful – cn/com…

For the commodityMessage array passed through the input loop,The fields bound to the V-model must be unique.Keep the field names of each prop in the loop consistent with the field names in the ruleForm bound to the V-ModelThat’s it. For example, in data:

RuleForm: {number: "",// number orderNumber:"",// orderNumber}, commodityMessage: [{label: "number", prop: "number",}, {label: "OrderNumber ", prop: "orderNumber", widths:'500'}Copy the code

So what we get is these two input fields,

About the Select selector

The value of the V-Model binding is the prop field of each object in the commodityMessage. We will add this field to ruleForm accordingly. The value of the selection box is the optionSelect in the loop object, the label in optionSelect is bound to the selected label text, and the value in optionSelect is bound to the selected value for example:

<el-select v-else-if="item.optionSelect && ! item.isDate" v-model="ruleForm[item.prop]" :placeholder="item.label ? 'Please enter '+ 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>Copy the code
RuleForm: {site:"", // site}, commodityMessage: [{label: "site", prop: "site", optionSelect: [{label: "all ", value: "Shanghai"}, {value: label: "snack area", "Beijing"}},Copy the code

Here’s what we got:

About time pickers

We’re probably going to need a time picker, so I’m going to write it briefly hereUse it in a similar way to the input box, simply adding isDate: True to the object in the commodityMessage is the time picker

RuleForm: {startDate: ",}, commodityMessage: [{label: "order time ", prop: "startDate", isDate:true},Copy the code

We can see the effect:

About the button

Most of the input fields use some buttons, and I’ve simply wrapped the searchBtns array here. Name is the text of the button, fun is the function name of the button, type is the color of the button, and then bound events in the component. The field name is fun for the searchBtns. Such as:

<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>
Copy the code

To use:

Data (){return{searchBtns: [{name: "search ", fun:'onSearch'}, {name:" export ", fun:'exportFun'}, {name: "Empty search criteria ", fun:'emptyFun', type:'warning'},],}}, methods: {onSearch(){console.log(' click search button ', this.ruleform); }, exportFun(){console.log(' export '); }, emptyFun(){console.log(' empty search criteria '); }},Copy the code

Create a search.vue in the Components folder

<template> <div> <! -- Inline ="true" inline form mode --> <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 ? 'Please enter '+ 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 ? 'Please enter '+ 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 =" to "start-placeholder=" start date" end-placeholder=" end date "> </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>Copy the code

Parent component use

<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 binding site:"", // site number: OrderNumber :"",// orderNumber orderType: "",// order status startDate: ",}, commodityMessage: [// {label: "order time ", prop: "StartDate ", isDate:true}, {label: "site", prop: "site", optionSelect: [{label:" all ", value: "Shanghai"}, {label: Value: "snack area", "Beijing"}}, {label: "number", prop: "number",}, {label: "number", prop: "OrderNumber ", Widths :'500'}, {label: "order status ", prop: "orderType", optionSelect: [{label:" all ", value: "Shanghai"}, {label: "to be paid ", value:" ZHIfu "}, {label: "paid ", value: "yizhifu"}, {label:" refund ", value: "Yituikuan"}]},], searchRules: {// check orderNumber: [{required: true, message: "please enter the orderNumber ", trigger: "blur"}, {min: 3, Max: 5, message: "Length between 3 and 5 characters ", trigger: "blur"}], number: [{min: 3, Max: 5, message: "Length between 3 and 5 characters ", trigger: "blur"}],}, searchBtns: [// buttons {name:" search ", fun:'onSearch'}, {name: "Export", fun: 'exportFun'}, {name: "empty search criteria", fun: 'emptyFun, type:' warning '},]}; }, methods: {onSearch(){console.log(' click the search button ', this.ruleform); }, exportFun(){console.log(' export '); }, emptyFun(){console.log(' empty search criteria '); }}}; </script> <style lang="scss" scoped> </style>Copy the code