vue中v-model指令與.sync修飾符的區別詳解
v-model
<!--父組件--> <template> <!--v-model 指令是語法糖--> <Child v-model="model"></Child> <!-- 把 v-model 指令展開後相當於下面的代碼 --> <!-- v-model綁定的默認事件是input,默認prop是value屬性 --> <Child :value="model" @input="model = $event"></Child> </template>
你也可以通過子組件中的model選項來修改v-model綁定的的默認事件和prop自定義屬性:
//子組件 export default { model: { prop: 'checked', event: 'change' } }
所以相應的父組件使用v-model的時候的等效操作為:
<template> <Child :checked="model" @change="model = $event"></Child> <template>
v-model通常用於表單控件,因為這樣子組件有更強的控制能力
.sync
<!-- 父組件 --> <template> <!-- .sync添加於v2.4,他能用於修改傳遞到子組件中的屬性 --> <Child :xxx.sync="model"></Child> <!-- 等效於下面的代碼 --> <Child :xxx = "model" @update:xxx = "model = $event"></Child> </template> <!-- 子組件 --> <input :value="xxx" @input = "$emit('update:xxx', $event.target.value)"/>
這裡綁定的屬性名稱xxx可以更改,相應的屬性名也會變化:
<!-- 父組件 --> <template> <Child :foo.sync="model"></Child> </template> <!-- 子組件 --> <input :value = "foo" @input = "$emit('update:foo', $event.target.value)"/>
.sync的原理用到瞭子組件向父組件派發事件的$emit方法。其應用場景為子組件想修改父組件傳遞的屬性;
.sync修飾符的控制能力都在父組件,事件名稱也是相對固定的update:xxx
兩者本質都是一樣,並沒有任何區別: “監聽一個觸發事件”=”(val) => value = val”。
細微之處的區別
1.隻不過v-model默認對應的是input或者textarea等組件的input事件,如果在子組件替換這個input事件,其本質和.sync修飾符一模一樣。比較單一,不能有多個。
// 子組件可以用自定義事件,來替換v-model默認對應的原生input事件,隻不過我們需要在子組件手動 $emit model: { prop: "value", event: "update" },
一個組件可以多個屬性用.sync修飾符,可以同時”雙向綁定多個“prop”,而並不像v-model那樣,一個組件隻能有一個。
總結功能作用場景:
1.v-model針對更多的是最終操作結果,是雙向綁定的結果,是value,是一種change操作。
比如:輸入框的值、多選框的value值列表、樹結構最終綁定的id值列表(ant design和element都是)、等等…
2..sync針對更多的是各種各樣的狀態,是狀態的互相傳遞,是status,是一種update操作。
比如:組件loading狀態、子菜單和樹結構展開列表(狀態的一種)、某個表單組件內部驗證狀態、等等….
但是也有例外,就是v-model也可以替代部分.sync的情況,這是針對於這個組件隻有一個功能就是切換狀態的時候,這個狀態就是最終操作值,這時候可以替代.sync修飾符。使用兩種不同的方式雙向綁定,能夠讓我們快速理解組件的結構。
推薦閱讀:
- vue自定義組件如何通過v-model指令控制組件的隱藏、顯示
- Vue重要修飾符.sync對比v-model的區別及使用詳解
- vue修飾符v-model及.sync原理及區別詳解
- vue原生input輸入框原理剖析
- vue實戰中的一些實用小魔法匯總