自定義組件的 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)" : 觸發的事件