理解v-model
參考文檔:
v-model一般用於雙向綁定:
以下內容來自:vue 自定義組件使用v-model
<input v-model="something">
v-model指令其實是下面的語法糖包裝而成:
<input
:value="something"
@:input="something = $event.target.value">
在一個組件上使用 v-model 時,會簡化爲:
<custom-input
:value="something"
@input="value => { something = value }">
</custom-input>
因此,對於一個帶有 v-model 的組件,它應該如下:
- 接收一個 value prop
- 觸發 input 事件,並傳入新值
利用 $emit 觸發 input 事件:
this.$emit('input', value);
官方文檔中有講到自定義組件的 v-model
允許一個自定義組件在使用
v-model
時定製 prop 和 event。默認情況下,一個組件上的 v-model
會把value
用作 prop 且把input
用作 event,但是一些輸入類型比如單選框和複選框按鈕可能想使用value
prop 來達到不同的目的。使用model
選項可以迴避這些情況產生的衝突。
如下的例子:
PersonalInfo.vue
<template>
<div>
<select
:value="phoneInfo.areaCode"
placeholder="區號"
@change="handleAreaCodeChange"
>
<option value="+86">+86</option>
<option value="+60">+60</option>
</select>
<input
:value="phoneInfo.phone"
type="number"
placeholder="手機號"
@input="handlePhoneChange"
/>
<input
:value="zipCode"
type="number"
placeholder="郵編"
@input="handleZipCodeChange"
/>
</div>
</template>
<script>
export default {
name: "PersonalInfo",
model: {
prop: "phoneInfo", // 默認 value
event: "change" // 默認 input
},
props: {
phoneInfo: Object,
zipCode: String
},
methods: {
handleAreaCodeChange(e) {
this.$emit("change", {
...this.phoneInfo,
areaCode: e.target.value
});
},
handlePhoneChange(e) {
this.$emit("change", {
...this.phoneInfo,
phone: e.target.value
});
},
handleZipCodeChange(e) {
this.$emit("update:zipCode", e.target.value);
}
}
};
</script>
<template>
<div>
<PersonalInfo v-model="phoneInfo" :zip-code.sync="zipCode" />
<PersonalInfo
:phone-info="phoneInfo"
:zip-code="zipCode"
@change="val => (phoneInfo = val)"
@update:zipCode="val => (zipCode = val)"
/>
phoneInfo: {{ phoneInfo }}
<br />
zipCode: {{ zipCode }}
</div>
</template>
<script>
import PersonalInfo from "./PersonalInfo";
export default {
components: {
PersonalInfo
},
data() {
return {
phoneInfo: {
areaCode: "+86",
phone: "111"
},
zipCode: "222"
};
}
};
</script>
...this
表示的是對象的擴展