自定義組件的 v-model
一個組件上的 v-model 默認會利用名為 value 的 prop 和名為 input 的事件,但是像單選框、復選框等類型的輸入控件可能會將 value 特性用於不同的目的。model 選項可以用來避免這樣的沖突:
Vue.component('base-checkbox', { model: { prop: 'checked', event: 'change' }, props: { checked: Boolean }, template: ` <input type="checkbox" v-bind:checked="checked" v-on:change="$emit('change', $event.target.checked)" > ` })
現在在這個組件上使用 v-model 的時候:
<base-checkbox v-model="lovingVue"></base-checkbox>
這里的 lovingVue 的值將會傳入這個名為 checked 的 prop。同時當 <base-checkbox> 觸發一個 change 事件並附帶一個新的值的時候,這個 lovingVue 的屬性將會被更新。
注意你仍然需要在組件的 props 選項里聲明 checked 這個 prop。
原來的沒有封裝的代碼:
<FormItem label="適用胸型" prop="chestShape"> <Select multiple v-model="chestShape" @on-change="changeChestShape"> <Option v-for="(item,index) in chestShapeReqList" :value="item.dictValue" :key="index" >{{ item.dictLabel }}</Option> </Select> </FormItem> <FormItem label="有無鋼圈" prop="hasSteel"> <Select multiple v-model="hasSteel" @on-change="changeHasSteel"> <Option v-for="(item,index) in hasSteelReqList" :value="item.dictValue" :key="index" >{{ item.dictLabel }}</Option> </Select> </FormItem> <FormItem label="功能" prop="hasFunction"> <Select multiple v-model="hasFunction" @on-change="changwHasFunction"> <Option v-for="(item,index) in hasFunctionReqList" :value="item.dictValue" :key="index" >{{ item.dictLabel }}</Option> </Select> </FormItem> <FormItem label="壓力" prop="pressure"> <Select multiple v-model="pressure" @on-change="changePressure"> <Option v-for="(item,index) in pressureReqList" :value="item.dictValue" :key="index" >{{ item.dictLabel }}</Option> </Select> </FormItem> <FormItem label="組合形式" prop="makeupType"> <Select multiple v-model="makeupType" @on-change="changeMakeupType"> <Option v-for="(item,index) in makeupTypeReqList" :value="item.dictValue" :key="index" >{{ item.dictLabel }}</Option> </Select> </FormItem>
這段代碼里面的相識度很高 我們可以封裝起來
子組件 :
新建文件 select/seclect.vue
<template>
<FormItem :label="label" :prop="prop">
<Select :multiple="multiple" v-if="listData.length>0" :value="modelValue" @change="updateVal($event.target.value)" >
<Option
v-for="(item,index) in listData"
:value="item.dictValue"
:key="index"
>{{ item.dictLabel }}</Option>
</Select>
</FormItem>
</template>
<script>
export default {
name: 'com-select',
props: {
listData: {
type: Array,
default: () => []
},
label:String,
multiple:Boolean,
prop:String,
modelValue:Array,
},
model: {
prop: 'modelValue',
event: 'selectData'
},
data () {
return {
}
},
computed: {
},
methods: {
updateVal(val){
this.$emit('selectData',val)
}
}
}
</script>
從官網上看到,v-model在內部為不同的輸入元素使用不同的屬性並拋出不同的事件:
text和textarea元素使用value屬性和input事件
checkbox和radio使用checked屬性和change事件
select使用value和change事件
因為自定的組件並沒有默認的value和input事件,在使用時,我們需要按照上面那樣顯式的去聲明定義這些東西。這時,需要model選項,在定義組件的時候,指定prop的值和監聽的事件。
model: { prop: 'modelValue', event: 'selectData' },
model 選項中的prop 對應 =》 :value="modelValue" 的名字
model 選項中的 event 對應的是 this.$emit('selectData',val) 的 事件名字 this.$emit('selectData',val)
父組件:
引入子組件
import SelectCom from '../../components/Select/Select'
使用組件
components: {
SelectCom
},
<SelectCom label="基礎風格" :listData="productStyleList" v-model="sty" prop="style" :multiple="multiple" @selectData="styl(e)" />
productStyleList 是傳遞進去的數組
v-model="sty" 雙向綁定的值
@selectData="styl(e)" : 觸發的事件
