vue 中v-model 比較基礎的用法是在表單控件中,建立雙向數據綁定,可以更新數據並負責監聽html
用戶的輸入事件vue
實例代碼數組
<input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p> // 這裏是監聽了輸入框的input 事件,並將其value賦值給message。 ==》 <input v-bind:value="message" v-on:input = "message = $event.target.value" >
詳細解釋ide
這裏根據文檔上看,指出v-model 只是一種語法糖,一樣使用checkbox 時,咱們也使用了v-model 來更新 當前複選框是否是在被選中狀態,這裏監聽的是change 事件,函數
<my-checkbox :checked = "checked" @change ="(val)=>{checked =val}" Value = "other" > </my-checkbox>
在checkbox 中,就能夠使用value屬性去作其它事情,
v-model 指令對於不一樣的 type 類型會綁定在不一樣的事件上,查看vue.common.js 中的代碼就能夠發現:ui
if (el.component) { genComponentModel(el, value, modifiers); // component v-model doesn't need extra runtime return false } else if (tag === 'select') { genSelect(el, value, modifiers); } else if (tag === 'input' && type === 'checkbox') { genCheckboxModel(el, value, modifiers); } else if (tag === 'input' && type === 'radio') { genRadioModel(el, value, modifiers); } else if (tag === 'input' || tag === 'textarea') { genDefaultModel(el, value, modifiers); } else if (!config.isReservedTag(tag)) { genComponentModel(el, value, modifiers);
v-model會根據input 標籤中的type 類型不一樣, 相應的使用不一樣的 方法。this
再看到 type=「checkbox」 對應的方法,spa
this.listener = function () { var model = self._watcher.value; // 獲取綁定指令 的 數組,在chang 事件發生時,時刻操做value 數組的變化 if (isArray(model)) { var val = self.getValue(); if (el.checked) { if (indexOf(model, val) < 0) { // checkbox 已經被勾選後,首先在model數組中查找有沒有被勾選checkbox 的對應value,沒有的的話就加入進去,這裏也能夠推斷出在v-model 綁定在一組checkbox中時,能夠記錄全部的選中的值。 model.push(val); } } else { // checkbox 被取消,就在model中 刪除checkbox 對應的value, model.$remove(val); } } else { self.set(getBooleanValue()); } }; // 將this.listener 函數綁定到 input 的 chang 事件中去, 在checkbox 發生變化時, this.on('change', this.listener);
上面也是從vue.js 中截取的代碼, 就能夠用來解釋官網中這段實例:code
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> <label for="jack">Jack</label> <input type="checkbox" id="john" value="John" v-model="checkedNames"> <label for="john">John</label> <input type="checkbox" id="mike" value="Mike" v-model="checkedNames"> <label for="mike">Mike</label> <br> <span>Checked names: {{ checkedNames }}</span>
裏面的checkedNames 能夠保存全部已經被勾選的input 對應的value ,還不會有重複的值。component
官方示例
而後就聯想到了ElementUI
中 <el-checkbox-group/>
和<el-checkbox/>
兩個組件嵌套在一塊兒使用的場景
<el-checkbox-group v-model = "checkAll" @change = "handleChange" > <el-checkbox v-for="(value,index) in scope.row.values"></el-checkbox> <el-checkbox-group>
checkAll
數組中就保存着 內部 elCheckbox 組件對應全部已經勾選的數組,
查看ElementUI 源碼中 checkbox.vue 對應文件(只截取對應功能片段):
checkbox.vue template: <input v-else class="el-checkbox__original" type="checkbox" :disabled="disabled" :value="label" :name="name" v-model="model" @change="handleChange" @focus="focus = true" @blur="focus = false"> script: methods:{ handleChange(ev) { this.$emit('change', ev); if (this.isGroup) { this.$nextTick(_ => { this.dispatch('ElCheckboxGroup', 'change', [this._checkboxGroup.value]); // 自定義dispatch 方法,向上遍歷找到parent組件 名字是ElCheckboxGroup 的父組件,並觸發對應的change事件。 }); } } }
this.dispatch 找到的父組件就是 checkboxGroup組件,
checkboxGroup.vue template <div class="boxGroup-class"> <slot > </slot> </div> //裏面沒有註冊任何 change 方法 script : watch: { value(value) { this.dispatch('ElFormItem', 'el.form.change', [value]); } } // 只是watch 了value 屬性。
由於在
<el-checkbox-group v-model = "checkAll" /> === <el-checkbox-group @change = "(value) ={checkAll = value}" :value="checkAll"/>
也是利用了 v-model 的語法糖。