vue中v-model的學習
v-model在表單元素input、radio、checkBox、textarea創建雙向數據綁定,他會根據類型選取正確的方法來更新元素,本質不過是語法糖,負責監聽用戶的輸入操作以更新數據並對一些極端場景進行一些特殊處理
語法糖:也譯為糖衣語法,是由英國電腦科學家彼得·約翰·蘭達(Peter J. Landin)發明的一個術語,指電腦語言中添加的某種語法,這種語法對語言的功能並沒有影響,但是更方便程式設計師使用。通常來說使用語法糖能夠增加程式的可讀性,從而減少程式程式碼出錯的機會。
官方文檔連接://cn.vuejs.org/v2/guide/forms.html
新認識到的知識點:
.lazy
在默認情況下,v-model 在每次 input 事件觸發後將輸入框的值與數據進行同步 (除了上述輸入法組合文字時)。你可以添加 lazy 修飾符,從而轉為在 change 事件_之後_進行同步:
<!-- 在「change」時而非「input」時更新 --> <input v-model.lazy="msg">
.number
如果想自動將用戶的輸入值轉為數值類型,可以給 v-model 添加 number 修飾符
<input v-model.number="age" type="number">
這通常很有用,因為即使在 type="number" 時,HTML 輸入元素的值也總會返回字元串。如果這個值無法被 parseFloat() 解析,則會返回原始的值。
.trim
自動去除空格
<input v-model.trim="msg">
那麼在組件中如何使用呢?
首先v-model是寫在父組件中的
<VueRadio :msgs="strs" v-model="defaultValue"/>
因為vue也說過,v-model本質上是一個語法糖,所以以上程式碼是指上是
<VueRadio v-bind:checked="defaultValue" v-on:change="defaultValue= arguments[0]"> </VueRadio>
其實也就是表單元素的值和一個change事件,首先可以將父組件的默認值發送給子組件,子組件在發生值的變化時,父組件也能接收到。在input中,標識value和input默認值,在checkbox中標識checked和change
以上為在radio以及checkbox中v-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)" >' })
等價於
<base-checkbox v-model="lovingVue"></base-checkbox>
這裡的 lovingVue 的值將會傳入這個名為 checked 的 prop。同時當 <base-checkbox> 觸發一個 change 事件並附帶一個新的值的時候,這個 lovingVue 的 property 將會被更新。
注意你仍然需要在組件的 props 選項里聲明 checked 這個 prop。
接下來是子組件中的使用
<template>
<div>
<div v-for="(str,index) in msgs" :key="index">
<div>題目{{index+1}}
<div v-for="(st,index) in str" :key="index">
<div class="radio" v-if="st.disabled == true">
<input type="radio" v-on:change="$emit('change', $event.target.value)" :name="st.name" :value="st.value"/><span>{{st.value}}</span>
</div>
<div v-else>
<div class="radio" v-if="st.value == defaultV">
<input type="radio"
:name="st.name" :value="st.value" checked
v-on:change="$emit('change', $event.target.value)"/><span>{{st.value}}</span>
</div>
<div class="radio" v-else>
<input type="radio"
:name="st.name" :value="st.value"
v-on:change="$emit('change', $event.target.value)"/><span>{{st.value}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'VueRadio',
props: {
msgs: Array,
defaultV:String
},
model: {
prop: 'defaultV',
event: 'change',
},
}
</script>
<style scoped>
.radio{
border: 1px solid #409eff;
width: 40px;
border-radius: 4px;
margin-bottom: 5px;
}
span{
color: #409eff;
}
</style>
主要看標紅的幾處,以下為分解解釋,其實文檔中有提示,注意你仍然需要顯性聲明 checked 屬性。所以還是主要再聲明一個默認值,然後就可以使用了。

這樣就可以使用了,完整程式碼如下
父組件
<template> <div id="app"> <VueRadio :msgs="strs" v-model="defaultValue"/> <h1>{{defaultValue}}</h1> </div> </template> <script> import VueRadio from './components/VueRadio.vue' export default { components: { VueRadio }, data() { return { strs: [], defaultValue:"A" } }, created() { var strsTemp = [] for (var i = 0; i < 1; i++) { var rId = "r"+i; var st2 = [ { name: rId, value: "A" }, { name: rId, value: "B",disabled:true }, { name: rId, value: "C" } ]; strsTemp.push(st2) } this.strs = strsTemp; } } </script>
子組件
<template>
<div>
<div v-for="(str,index) in msgs" :key="index">
<div>題目{{index+1}}
<div v-for="(st,index) in str" :key="index">
<div class="radio" v-if="st.disabled == true">
<input type="radio" v-on:change="$emit('change', $event.target.value)" :name="st.name" :value="st.value"/><span>{{st.value}}</span>
</div>
<div v-else>
<div class="radio" v-if="st.value == defaultV">
<input type="radio"
:name="st.name" :value="st.value" checked
v-on:change="$emit('change', $event.target.value)"/><span>{{st.value}}</span>
</div>
<div class="radio" v-else>
<input type="radio"
:name="st.name" :value="st.value"
v-on:change="$emit('change', $event.target.value)"/><span>{{st.value}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'VueRadio',
props: {
msgs: Array,
defaultV:String
},
model: {
prop: 'defaultV',
event: 'change',
},
}
</script>
<style scoped>
.radio{
border: 1px solid #409eff;
width: 40px;
border-radius: 4px;
margin-bottom: 5px;
}
span{
color: #409eff;
}
</style>
實現效果

參考鏈接://juejin.cn/post/6844903490653782029
//www.jianshu.com/p/695ca638783a

