最近项目打算重构,项目的模块几乎都是以后台查询展示的传统的增删改差模式,所以卑微的我想要自己封装一下查询form,先上效果图

子组件页面:

  1 <template>
  2   <div class="sumbit-form">
  3     <el-form
  4       :model="value"
  5       :rules="rules"
  6       ref="ruleForm"
  7       label-width="100px"
  8       class="demo-ruleForm"
  9     >
 10       <slot name="formItem" />
 11       <template v-for="(item, index) in formConfig.formItemList">
 12         <el-row :key="index">
 13           <template v-for="(i, k) in item">
 14             <el-col :span="8" :key="k">
 15               <template
 16                 v-if="
 17                   ['text', 'textarea', 'number', 'email'].indexOf(i.type) !== -1
 18                 "
 19               >
 20                 <el-form-item :label="i.label" :prop="i.prop ? i.prop : ''">
 21                   <el-input :type="i.type" v-model="value[i.name]"></el-input>
 22                 </el-form-item>
 23               </template>
 24               <template v-if="i.type === 'select'">
 25                 <el-form-item :label="i.label" :prop="i.prop ? i.prop : ''">
 26                   <el-select v-model="value[i.name]" placeholder="">
 27                     <el-option
 28                       v-for="(j, k) in i.optList"
 29                       :key="k"
 30                       :label="j.label"
 31                       :value="j.value"
 32                     ></el-option>
 33                   </el-select>
 34                 </el-form-item>
 35               </template>
 36               <template
 37                 v-if="
 38                   ['data', 'datetimerange', 'datetime'].indexOf(i.type) !== -1
 39                 "
 40               >
 41                 <el-form-item :label="i.label" :prop="i.prop ? i.prop : ''">
 42                   <el-date-picker
 43                     v-model="value[i.name]"
 44                     type="datetimerange"
 45                     range-separator="至"
 46                     start-placeholder="开始日期"
 47                     end-placeholder="结束日期"
 48                     value-format="yyyy-MM-dd HH:mm:ss"
 49                   >
 50                   </el-date-picker>
 51                 </el-form-item>
 52               </template>
 53               <template v-if="i.type == 'switch'">
 54                 <el-form-item :label="i.label" :prop="i.prop ? i.prop : ''">
 55                   <el-switch v-model="value[i.name]"></el-switch>
 56                 </el-form-item>
 57               </template>
 58               <template v-if="i.type == 'radio'">
 59                 <el-form-item :label="i.label">
 60                   <el-radio-group v-model="value[i.name]">
 61                     <el-radio
 62                       v-for="(j, k) in i.optList"
 63                       :label="j"
 64                       :key="k"
 65                     ></el-radio>
 66                   </el-radio-group>
 67                 </el-form-item>
 68               </template>
 69               <template v-if="i.type === 'Checkbox'">
 70                 <el-checkbox-group v-model="value[i.name]">
 71                   <el-checkbox
 72                     v-for="ch in i.checkboxs"
 73                     :label="ch.value"
 74                     :key="ch.value"
 75                     >{{ ch.label }}</el-checkbox
 76                   >
 77                 </el-checkbox-group>
 78               </template>
 79             </el-col>
 80           </template>
 81         </el-row>
 82       </template>
 83 
 84       <div class="searchBtn">
 85         <el-button-group>
 86           <el-button
 87             v-for="(item, index) in formConfig.operate"
 88             :key="index"
 89             size="small"
 90             :type="item.type"
 91             @click.stop.prevent="item.handleClick"
 92             >{{ item.name }}
 93           </el-button>
 94         </el-button-group>
 95         <slot name="operate"></slot>
 96       </div>
 97     </el-form>
 98   </div>
 99 </template>
100 <script>
101 export default {
102   props: {
103     formConfig: {
104       type: Object,
105       default: () => {}
106     },
107     value: {
108       type: Object,
109       default: () => {}
110     },
111     rules: {
112       type: Object,
113       default: () => {}
114     }
115   },
116   data() {
117     return {
118       isSearchLock: true
119     };
120   },
121   created() {},
122   methods: {
123     //子组件校验,传递到父组件
124     validateForm() {
126       let flag = null;
127       if (this.isSearchLock) {
128         this.$refs["ruleForm"].validate(valid => {
129           let vm = this;
130           if (valid) {
131             flag = true;
132             vm.isSearchLock = flag;
133           } else {
134             flag = false;
135             vm.isSearchLock = flag;
136             this.$message.error("保存信息不完整,请继续填写完整");
137             setTimeout(function() {
138               vm.isSearchLock = true;
139             }, 2000);
140           }
141         });
142         return flag;
143       }
144     },
145     resetFields() {
146       this.$refs["ruleForm"].resetFields();
147     }
148   },
149   mounted() {}
150 };
151 </script>
152 <style lang="less">
153 .el-form-item__content {
154   .el-date-editor--datetimerange {
155     width: 100%;
156   }
157 }
158 .searchBtn {
159   text-align: center;
160   .el-button {
161     background-color: #4a91d7;
162     width: 96px;
163     color: #fff;
164     &:first-child {
165       margin-right: 5px;
166     }
167     &:hover {
168       background-color: #257ccd;
169       border-color: #257ccd;
170     }
171   }
172 }
173 </style>

父组件里面调用

  1 <flight-form
  2           ref="childRules"
  3           :formConfig="formConfig"
  4           :value="form"
  5           :rules="rules"
  6 ></flight-form>
  7 <script>
  8 import flightForm from "@/components/flightForm.vue";
  9 export default{
 10 components: {
 11     flightForm ,
 12 
 13   },
 14     data() {
 15         return {
 16           formConfig: {
 17         formItemList: [
 18           [
 19             {
 20               type: "text",
 21               prop: "airport",
 22               label: "站点",
 23               name: "airport",
 24               placeholder: "请输入站点"
 25             },
 26             {
 27               type: "select",
 28               prop: "importOrExport",
 29               label: "进出港",
 30               name: "importOrExport",
 31               placeholder: "请输入进出港",
 32               optList: [
 33                 {
 34                   value: "",
 35                   label: ""
 36                 },
 37                 {
 38                   value: "进港",
 39                   label: "进港"
 40                 },
 41                 {
 42                   value: "出港",
 43                   label: "出港"
 44                 }
 45               ]
 46             },
 47             {
 48               type: "select",
 49               prop: "mainOrSubBill",
 50               name: "mainOrSubBill",
 51               label: "主分单",
 52 
 53               placeholder: "请输入主分单",
 54               optList: [
 55                 {
 56                   value: "",
 57                   label: ""
 58                 },
 59                 {
 60                   value: "主分",
 61                   label: "主分"
 62                 },
 63                 {
 64                   value: "主单",
 65                   label: "主单"
 66                 }
 67               ]
 68             }
 69           ],
 70           [
 71             {
 72               type: "datetimerange",
 73               name: "pickerdata",
 74               label: "选择时间",
 75               prop: "pickerdata",
 76               dateFormate: "yyyy-MM-dd HH:mm:ss"
 77             },
 78             {
 79               type: "text",
 80               name: "largeClass",
 81               prop: "largeClass",
 82               label: "大类",
 83               placeholder: "请输入大类"
 84             },
 85             {
 86               type: "select",
 87               name: "isDomestic",
 88               prop: "isDomestic",
 89               value: "国内",
 90               label: "国内/国际",
 91               placeholder: "请输入国内/国际",
 92               optList: [
 93                 {
 94                   value: "",
 95                   label: ""
 96                 },
 97                 {
 98                   value: "国内",
 99                   label: "国内"
100                 },
101                 {
102                   value: "国际",
103                   label: "国际"
104                 }
105               ]
106             }
107           ],
108           [
109             {
110               type: "switch",
111               name: "save",
112               prop: "save",
113               label: "保存"
114             },
115             {
116               type: "radio",
117               name: "radio",
118               prop: "radio",
119               label: "活动类型",
120               optList: ["演唱会", "球赛"]
121             },
122             {
123               type: "Checkbox",
124               label: "爱好",
125               prop: "Checkbox",
126               name: "Checkbox",
127               checkboxs: [
128                 { label: "羽毛球", value: "badminton" },
129                 { label: "篮球", value: "basketball" },
130                 { label: "足球", value: "football" },
131                 { label: "兵乓球", value: "pong" }
132               ]
133             }
134           ]
135         ],
136 
137         operate: [
138           {
139             type: "primary",
140             name: "查询",
141             handleClick: this.search
142           },
143           {
144             type: "primary",
145             name: "重置",
146             handleClick: this.add
147           }
148         ]
149       },
150       rules: {
151         airport: [{ required: true, message: "请输入站点", trigger: "blur" }],
152         importOrExport: [
153           { required: true, message: "请输入进出港", trigger: "blur" }
154         ],
155         largeClass: [
156           { required: true, message: "请输入大类", trigger: "blur" }
157         ],
158         mainOrSubBill: [
159           { required: true, message: "请输入主分单", trigger: "blur" }
160         ],
161         isDomestic: [
162           { required: true, message: "请输入国内/国际", trigger: "blur" }
163         ],
164         pickerdata: [
165           { required: true, message: "请输入时间", trigger: "change" }
166         ]
167       },
168       form: {
169         isDomestic: "国内",
170         mainOrSubBill: "主分",
171         importOrExport: "进港",
172         airport: "",
173         largeClass: "",
174         Checkbox: [],
175         pickerdata: [],
176         save: false,
177         radio: ""
178       },
179         }
180     },
181      methods: {
182         // 查询
183     search() {
184       let flag = this.$refs["childRules"].validateForm();
185       if (flag) {
186         console.log(this.form);
187       }
188     },
189     // 新增或重置
190     add() {
191       this.$refs["childRules"].resetFields();
192     },
193     },
194     }
195 }
196 </script>

父组件里面的form传给子组件是传默认值的,

卑微前端,记录自己的项目封装的组件,方便以后自己用,如果有哪里不合理,请各路大神多多指教。