自定義元件實現v-model,並通過element的form表單校驗
阿新 • • 發佈:2022-05-27
做專案時,我們經常會遇到表單項不單單是input,select框這些基礎表單項,有時候會在表單裡出現一些較為複雜的自定義元件,比如下圖中的插槽型別元件:
插槽元件我實現了v-model的用法,程式碼如下:
slotTypeSelector:
1 <template> 2 <div class="item-list"> 3 <div 4 class="item" 5 :class="activeSlotType === '1' ? 'actived' : ''" 6 @click="handleSelectSlotType('type1', '1')" 7> 8 <dv-border-box-11 ref="type1" title="標題"></dv-border-box-11> 9 </div> 10 <div 11 class="item" 12 :class="activeSlotType === '2' ? 'actived' : ''" 13 @click="handleSelectSlotType('type2', '2')" 14 > 15 <dv-border-box-4 ref="type2"> 16<!-- <div class="title">標題</div> --> 17 </dv-border-box-4> 18 </div> 19 <div 20 class="item" 21 :class="activeSlotType === '3' ? 'actived' : ''" 22 @click="handleSelectSlotType('type3', '3')" 23 > 24 <dv-border-box-10 ref="type3"></dv-border-box-10> 25</div> 26 <div 27 class="item" 28 :class="activeSlotType === '4' ? 'actived' : ''" 29 @click="handleSelectSlotType('type4', '4')" 30 > 31 <dv-border-box-13 ref="type4"> 32 <!-- <div class="title">標題</div> --> 33 </dv-border-box-13> 34 </div> 35 </div> 36 </template> 37 38 <script> 39 export default { 40 name: "SlotTypeSelector", 41 components: {}, 42 model: { 43 prop: 'slotType', 44 event: 'change' 45 }, 46 props: { 47 slotType: { 48 type: String, 49 default: "", 50 }, 51 }, 52 data() { 53 return { 54 activeSlotType: this.slotType, 55 }; 56 }, 57 58 computed: {}, 59 watch: { 60 slotType(newV, oldV) { 61 this.activeSlotType = newV; 62 }, 63 }, 64 mounted() {}, 65 66 methods: { 67 handleSelectSlotType(ref, type) { 68 this.activeSlotType = type; 69 this.$refs[`${ref}`].initWH(); 70 this.$emit("change", this.activeSlotType); 71 }, 72 }, 73 }; 74 </script> 75 <style lang="scss" scoped> 76 .item-list { 77 display: flex; 78 flex-wrap: wrap; 79 justify-content: flex-start; 80 .item { 81 width: 500px; 82 height: 270px; 83 margin: 0 10px 10px 0; 84 cursor: pointer; 85 display: flex; 86 justify-content: center; 87 align-items: center; 88 padding: 10px; 89 box-sizing: border-box; 90 background: #000; 91 color: #fff; 92 ::v-deep .dv-border-box-4 .border-box-content .title { 93 position: absolute; 94 left: 40px; 95 top: 20px; 96 font-size: 18px; 97 } 98 ::v-deep .dv-border-box-13 .border-box-content .title { 99 position: absolute; 100 left: 13px; 101 top: 13px; 102 font-size: 18px; 103 } 104 } 105 .actived { 106 border: 6px solid rgb(139, 190, 232); 107 } 108 } 109 </style
父元件使用方式如下:
1 <div id="slotDetails"> 2 <jhe-dialog-schema-form 3 ref="slotRuleForm" 4 :model="dialogFormData" 5 :schema="dialogFormSchema" 6 :options="dialogFormOptions" 7 :dialog-visible="dialogVisible" 8 :dialog-form-title="dialogFormTitle" 9 :dialog-form-width="dialogFormWidth" 10 :label-position="labelPosition" 11 :rules="rules" 12 @beforeClose="beforeClose" 13 > 14 <el-form-item 15 slot="slotType" 16 ref="slotTypeRef" 17 label="插槽型別" 18 label-width="100px" 19 prop="slotType" 20 > 21 <slot-type-selector v-model="dialogFormData.slotType" @change="handleSlotTypeChanged"></slot-type-selector></el-form-item> 22 <div slot="dialog-form-footer"> 23 <jhe-button @click="submitForm('slotRuleForm')">保 存</jhe-button> 24 <jhe-button @click="previewSlot('slotRuleForm')">預 覽</jhe-button> 25 <jhe-button @click="beforeClose">關 閉</jhe-button> 26 </div> 27 </jhe-dialog-schema-form>
此時,v-mode的用法已經實現。
接下來就是自定義的插槽型別元件要通過form表單的校驗。網上查詢了很多資料,得知
元件 slotTypeSelector在 value props 變化時,沒有觸發 el-form 表單的 validate 表單校驗。
於是想辦法去觸發el-form 表單的 validate 表單校驗。
程式碼如下:
methods: { handleSlotTypeChanged(value) { // 新增change事件回撥,為了emit這個'el.form.change'事件! this.$refs.slotTypeRef.$emit('el.form.change', value); // 重點!自定義元件使用element的form表單校驗 },
slotType: [ { required: true, message: "請選擇插槽型別", trigger: ["change"], }, ],
至此就大功告成了!!!