是單向的。雖然vue有雙向繫結「v-model」,但是vue父子元件之間資料傳遞,仍然還是遵循單向資料流的,父元件可以向子元件傳遞props,但是子元件不能修改父元件傳遞來的props,子元件只能通過事件通知父元件進行資料更改。
本教學操作環境:windows7系統、vue3版,DELL G3電腦。
vue是單向資料流,資料流向是從上到下,從父元件傳遞到子元件的。
不要和vue的雙向資料繫結搞混了;雙向資料繫結說的是檢視和模板之間的渲染關係,並不是資料的流向關係!
vue父子元件之間資料傳遞是遵循單向資料流的,父元件可以向子元件傳遞props,但是子元件不能修改父元件傳遞來的props,子元件只能通過事件通知父元件進行資料更改。
1,單向資料流:
所有的 prop 都使得其父子 prop 之間形成了一個單向下行繫結:父級 prop 的更新會向下流動到子元件中,但是反過來則不行。這樣會防止從子元件意外變更父級元件的狀態,從而導致你的應用的資料流向難以理解。
額外的,每次父級元件發生變更時,子元件中所有的 prop 都將會重新整理為最新的值。這意味著你不應該在一個子元件內部改變 prop。如果你這樣做了,也將會改變父元件的狀態。
2,Prop是通過參照傳入的:
注意在 JavaScript 中物件和陣列是通過參照傳入的,所以對於一個陣列或物件型別的 prop 來說,在子元件中改變變更這個物件或陣列本身將會影響到父元件的狀態。
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 的觸發事件
v-model 不僅僅能在 input 上用,在元件上也能使用,拿官網上的demo看。
<currency-input v-model="price"></currency-input>
Vue.component('currency-input', {
template: '\
<span>\
$\
<input\
ref="input"\
v-bind:value="value"\
v-on:input="updateValue($event.target.value)"\
>\
</span>\
',
props: ['value'], // 為什麼這裡要用 value 屬性,value在哪裡定義的?
methods: {
// 不是直接更新值,而是使用此方法來對輸入值進行格式化和位數限制
updateValue: function (value) {
var formattedValue = value
// 刪除兩側的空格符
.trim()
// 保留 2 位小數
.slice(
0,
value.indexOf('.') === -1
? value.length
: value.indexOf('.') + 3
)
// 如果值尚不合規,則手動覆蓋為合規的值
if (formattedValue !== value) {
this.$refs.input.value = formattedValue
}
// 通過 input 事件帶出數值
// <!--為什麼這裡把 'input' 作為觸發事件的事件名?`input` 在哪定義的?-->
this.$emit('input', 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' 值作為給元件繫結事件時的事件名。這在寫元件時特別有用。
在建立類似核取方塊或者單選框的常見元件時,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('checkbox', {
tempalte: '<input type="checkbox" @change="change" :checked="currentValue"/>'
props: ['value'],
data: function () {
return {
//這裡為什麼要定義一個區域性變數,並用 prop 的值初始化它。
currentValue: this.value
};
},
methods: {
change: function ($event) {
this.currentValue = $event.target.checked;
this.$emit('input', this.currentValue);
}
})
登入後複製
在 Vue 2.2 版本,你可以在定義元件時通過 model 選項的方式來客製化 prop/event 。
從上面 v-model 的分析我們可以這麼理解,雙向資料繫結就是在單向繫結的基礎上給可輸入元素(input、textare等)新增了 change(input) 事件,來動態修改 model 和 view ,即通過觸發($emit)父元件的事件來修改mv來達到 mvvm 的效果。而 vue 元件間傳遞資料是單向的,即資料總是由父元件傳遞到子元件,子元件在其內部可以有自己維護的資料,但它無權修改父元件傳遞給它的資料,當開發者嘗試這樣做的時候,vue 將會報錯。這樣做是為了元件間更好的解耦,在開發中可能有多個子元件依賴於父元件的某個資料,假如子元件可以修改父元件資料的話,一個子元件變化會引發所有依賴這個資料的子元件發生變化,所以 vue 不推薦子元件修改父元件的資料,直接修改 props 會丟擲警告。流程圖如下:
所以,當你想要在子元件去修改 props 時,把這個子元件當成父元件那樣用,所以就有了
【相關推薦:、】
以上就是vue資料流是單向嗎的詳細內容,更多請關注TW511.COM其它相關文章!