首頁  >  文章  >  web前端  >  Vue 單向資料流的原理深入解析

Vue 單向資料流的原理深入解析

小云云
小云云原創
2017-12-22 13:10:292284瀏覽

本文主要介紹了深入理解Vue 單向資料流的原理,詳細的介紹了Vue 單向資料流的原理和使用,具有一定的參考價值,有興趣的可以了解一下,希望能幫助到大家。

單向資料流是什麼

單向資料流指只能從一個方向來修改狀態。下圖是單向資料流的極簡示意:

單向資料流的極簡示意

與單向資料流對對應的是雙向資料流(也叫雙向綁定)。在雙向資料流中,Model(可以理解為狀態的集合) 中可以修改自己或其他Model的狀態, 使用者的操作(如在輸入框中輸入內容)也可以修改狀態。這使得改變一個狀態有可能會觸發一連串的狀態的變化,最後很難預測最終的狀態是什麼樣的。使得程式碼變得很難調試。如下圖所示:

與雙向資料流比,在單向資料流中,當你需要修改狀態,完全重新開始走一個修改過的流程。這限制了狀態修改的方式,讓狀態變得可預測,容易調試。

單向資料流的使用情境

多個元件會共用狀態時,共用狀態和元件間(兄弟元件)通訊變的不容易。我們把共享狀態抽取出來,用單向資料流的方式會變得容易。

從v-model開始講起

1、v-model 用在input 元素上

v-model在使用的時候很像雙向綁定的(實際上也是。。。),但是Vue 是單項資料流,v-model 只是語法糖而已:


<input v-model="something" />
<input v-bind:value="something" v-on:input="something = $event.target.value" />

第一行的程式碼其實只是第二行的語法糖。然後第二行程式碼還能簡寫成這樣:


<input :value="something" @input="something = $event.target.value" />

要理解這行程式碼,首先你要知道input 元素本身有個oninput 事件,這是HTML5 新增加的,類似onchange ,每當輸入框內容發生變化,就會觸發oninput ,透過$event 把最新的value 傳遞給something。

我們仔細觀察語法糖和原始語法那兩行程式碼,可以得出一個結論: 在為input 元素加上v-model 屬性時,預設會把value 作為元素的屬性,然後把'input'事件作為即時傳遞value 的觸發事件

2、v-model 用在元件上

v-model 不僅能在input 上用,在元件上也能使用,拿官網上的demo看。


<currency-input v-model="price"></currency-input>
Vue.component(&#39;currency-input&#39;, {
 template: &#39;\
 <span>\
  $\
  <input\
  ref="input"\
  v-bind:value="value"\
  v-on:input="updateValue($event.target.value)"\
  >\
 </span>\
 &#39;,
 props: [&#39;value&#39;], // 为什么这里要用 value 属性,value在哪里定义的?
 methods: {
 // 不是直接更新值,而是使用此方法来对输入值进行格式化和位数限制
 updateValue: function (value) {
  var formattedValue = value
  // 删除两侧的空格符
  .trim()
  // 保留 2 位小数
  .slice(
   0,
   value.indexOf(&#39;.&#39;) === -1
   ? value.length
   : value.indexOf(&#39;.&#39;) + 3
  )
  // 如果值尚不合规,则手动覆盖为合规的值
  if (formattedValue !== value) {
  this.$refs.input.value = formattedValue
  }
  // 通过 input 事件带出数值
  // <!--为什么这里把 &#39;input&#39; 作为触发事件的事件名?`input` 在哪定义的?-->
  this.$emit(&#39;input&#39;, Number(formattedValue))
 }
 }
})

如果你知道這兩個問題的答案,那麼恭喜你真正掌握了v-model,如果你沒明白,那麼你可以看下這段程式碼:


<currency-input v-model="price"></currency-input>
所以在组件中使用时,它相当于下面的简写:
//上行代码是下行的语法糖
<currency-input :value="price" @input="price = arguments[0]"></currency-input>

所以,當元件加上v-model 屬性時,預設會把value 作為元件的屬性,然後把'input' 值當作給元件綁定事件時的事件名。這在寫入組件時特別有用。

3、v-model 的缺點和解決方案

在創建類似複選框或單選框的常見元件時,v-model就不好用了。


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

v-model 給我們提供好了value 屬性和oninput 事件,但是,我們需要的不是value 屬性,而是checked 屬性,並且當你點擊這個單選框的時候不會觸發oninput 事件,它只會觸發onchange 事件。

因為v-model 只是用到了input 元素上,所以這種情況好解決:


<input type="checkbox" :checked="value" @change="change(value, $event)"

當v-model 用到元件上時:


<checkbox v-model="value"></checkbox>

Vue.component(&#39;checkbox&#39;, {
 tempalte: &#39;<input type="checkbox" @change="change" :checked="currentValue"/>&#39;
 props: [&#39;value&#39;],
 data: function () {
  return {
   //这里为什么要定义一个局部变量,并用 prop 的值初始化它。
   currentValue: this.value
  };
 },
 methods: {
 change: function ($event) {
  this.currentValue = $event.target.checked;
  this.$emit(&#39;input&#39;, this.currentValue); 
 }
})

在Vue 2.2 版本,你可以在定義元件時透過model 選項的方式來自訂prop/event 。

4、vue 元件資料流

從上面v-model 的分析我們可以這麼理解,雙向資料綁定就是在單向綁定的基礎上給可輸入元素(input、textare等)加入了change(input) 事件,來動態修改model 和view ,即透過觸發($emit)父元件的事件來修改mv來達到mvvm 的效果。而vue 元件間傳遞資料是單向的,即資料總是由父元件傳遞到子元件,子元件在其內部可以有自己維護的數據,但它無權修改父元件傳遞給它的數據,當開發當者嘗試這樣做的時候,vue 將會報錯。這樣做是為了組件間更好的解耦,在開發中可能有多個子組件依賴於父組件的某個數據,假如子組件可以修改父組件數據的話,一個子組件變化會引發所有依賴這個數據的子元件發生變化,所以vue 不建議子元件修改父元件的數據,直接修改props 會拋出警告。流程圖如下:


所以,當你想要在子元件去修改props 時,把這個子元件當成父元件那樣用,所以就有了

1 、定義一個局部變量,並用prop 的值初始化它。
2、定義一個計算屬性,處理 prop 的值並回傳。

相關推薦:

vue.js中有關元件資料流問題的解決方案

一個php資料流應用的小例子

Python 資料流操作

以上是Vue 單向資料流的原理深入解析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn