Vue進階——解析V-MODEL

最近從新過了一遍VUE官方文檔,發現有些知識點官方解釋的不是很清楚,因此在此深刻解析一下,但願能幫到和我同樣看文檔遇到困惑的朋友們。html

 

 

 

這裏關於v-model,官方說明篇幅甚少,留下了一些疑問,下面詳細解析v-model知識點。vue

 

 

1、v-model用在input上ide

v-model雖然很像使用了雙向數據綁定的 Angular 的 ng-model,可是 Vue 是單項數據流v-model 只是語法糖而已:ui

 

// 最簡形式,省略了value的顯式綁定,省略了oninput的顯式事件監聽,是第二句代碼的語法糖形式
<
input v-model="sth" />
<input v-bind:value="sth" v-on:input="sth = $event.target.value" />

//第二句代碼的簡寫形式 <input :value="sth" @input="sth = $event.target.value" />

 

首先你要知道 ,在HTML5新特性中,input 元素自己就有個 oninput 事件,相似 onchange ,每當輸入框內容發生變化,就會觸發 oninput ,把輸入框最新的value值傳遞給 sth(第二句代碼)。
spa

關於$event,懂的朋友請忽略,$event知識點傳送門3d

 

咱們仔細觀察語法糖和後兩句完整版本代碼,能夠得出一個結論:code

在給 <input /> 元素添加 v-model 屬性時,默認會把 value 做爲v-model的屬性,默認把 'input' 事件做爲實時傳遞 value 的觸發事件,這就是官方文檔這句話的意思:component

 

2、v-model用在組件上htm

明白了v-model只是語法糖,它的默認值是value,默認監聽事件是oninput,咱們來看一個稍複雜的例子,它是將v-model使用在組件上。blog

 

相似於下圖的效果,父組件的 price 的初始值是 100,更改子組件的值能實時更新父組件的 price

<div id="demo">
  <currency-input v-model="price"></currentcy-input>
  // 其實是下列代碼
  //<currency-input v-bind:value="price" v-on:input=" price = arguments[0] "></currency-input>
 <span>{{price}}</span> </div> <script> Vue.component('currency-input', { template: ` <span> <input :value="value" <!--這裏之因此把 'input' 做爲事件名向父級傳遞,正是由於非語法糖形式中v-on:input監聽的是input事件--> @input="$emit('input', $event.target.value)" > </span> `, props: ['value'],// 這裏的value正是被簡寫掉的,因此語法糖形式你找不到這個value在哪裏綁定的,而在非語法糖形式找獲得 }) var demo = new Vue({ el: '#demo', data: { price: 100, } }) </script>

如今你必定對於v-model是語法糖形式理解更深入了,也對官方文檔的困惑一點點明瞭了。

 

3、v-model的不足與解決方案

它的不足在官方文檔也提出來了:

 

 

 咱們來看看具體是什麼意思。

在建立相似複選框或者單選框的常見組件時,v-model就很差用了。

<input type="checkbox" v-model="sth" />

v-model 給咱們默認提供了 value 屬性和 oninput 事件,可是在這裏咱們須要的不是 value 屬性,而是 checked 屬性,而且當你點擊這個單選框的時候不會觸發 oninput 事件,它只會觸發 onchange 事件。這就是問題所在。

 

這是 v-model 只用在 input 上的狀況,解決方案以下:

<input type="checkbox" :checked="status" @change="status = $event.target.checked" />

 

當v-model用在組件上時,解決方案以下:

<my-checkbox v-model="foo"></my-checkbox>

Vue.component('my-checkbox', {
  tempalte: `<input 
               type="checkbox"
               @change="$emit('input', $event.target.checked)"
               :checked="value"
             />`
  props: ['value'],
})

不明白的同窗能夠本身將語法糖形式寫成完整的非語法糖形式,再結合前面的講解進行分析。

 

4、在 Vue 2.2 版本,你能夠在定義組件時經過 model 選項的方式來定製 prop/event:

 

//在這個組件中使用 v-model
<base-checkbox v-model="lovingVue"></base-checkbox>

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)"
    >
  `
})

 

lovingVue 的值就會傳遞給 checked prop。當 <base-checkbox> 內部觸發一個 change 事件,而且傳遞一個新值,lovingVue 屬性就會進行更新。

注意,仍然須要在組件 props 選項中聲明 checked prop 屬性。

相關文章
相關標籤/搜索