父子組件之間的雙向綁定很是簡單,可是不少人由於是從Vue 2+開始使用的,可能不知道如何雙向綁定,固然最簡單的雙向綁定(單文件中)就是表單元素的v-model
了,例如<input type="text" />
它會響應表單元素的value
屬性,當輸入框文本改變時,會將value
值傳給v-model
所綁定的變量,若是同時設置v-model
和value
,value
屬性無效。javascript
歡迎來個人Vue技術羣交流:887516034html
v-model
當若干dom封裝成組件時,在父組件中使用子組件時,卻沒法在子組件標籤上使用v-model
,由於子組件標籤不是表單元素,這個時候,咱們須要自定義咱們想要的v-model
規則。vue
<!-- children.vue -->
<template>
<h1>{{ msg }}</h1>
</template>
<script> export default{ model:{ prop:'msg',//這個字段,是指父組件設置 v-model 時,將變量值傳給子組件的 msg event:'parent-event'//這個字段,是指父組件監聽 parent-event 事件 }, props:{ msg:String //此處必須定義和model的prop相同的props,由於v-model會傳值給子組件 }, mounted(){ //這裏模擬異步將msg傳到父組件v-model,實現雙向控制 setTimeout(_=>{ let some = '3秒後出現的某個值';//子組件本身的某個值 this.$emit('parent-event',some); //將這個值經過 emit 觸發parent-event,將some傳遞給父組件的v-model綁定的變量 },3000); } } </script>
複製代碼
<!-- parent.vue -->
<template>
<children v-model="parentMsg"></children>
</template>
<script> import children from 'path/to/children.vue'; export default{ components:{ children }, data(){ return{ parentMsg:'test' } }, watch:{ parentMsg(newV,oldV){ console.log(newV,oldV); //三秒後控制檯會輸出 //'3秒後出現的某個值','test' } } } </script>
複製代碼
你學會組件的自定義
v-model
了嗎 ? 若是是普通的表單元素,同理,監聽表單的input
或者change
事件,實時將value
或者checked
經過$emit
傳遞就能夠了。java
上述例子,是實現單個prop值的雙向綁定,當組件的需求須要複雜的操做,須要多個雙向值,是如何實現的呢。這裏須要用到之前被vue拋棄,後來又迴歸的.sync
修飾符。dom
事實上,這個比v-model
更加簡單異步
<!-- children.vue -->
<template>
<h1>{{ msg }}</h1>
</template>
<script> export default{ props:{ msg:String }, mounted(){ //這裏模擬異步將msg傳到父組件v-model,實現雙向控制 setTimeout(_=>{ let some = '3秒後出現的某個值';//子組件本身的某個值 this.$emit('update:msg',some); //將這個值經過 emit //update爲固定字段,經過冒號鏈接雙向綁定的msg,將some傳遞給父組件的v-model綁定的變量 },3000); } } </script>
複製代碼
<!-- parent.vue -->
<template>
<children :msg.sync="parentMsg"></children>
<!-- 此處只需在平時經常使用的單向傳值上加上.sync修飾符 -->
</template>
<script> import children from 'path/to/children.vue'; export default{ components:{ children }, data(){ return{ parentMsg:'test' } }, watch:{ parentMsg(newV,oldV){ console.log(newV,oldV); //三秒後控制檯會輸出 //'3秒後出現的某個值','test' } } } </script>
複製代碼
此處須要注意,雖然加上.sync
便可雙向綁定,可是仍是要依靠子組件$emit
去觸發update:prop名
實現修改父組件的變量值實現雙向數據流,若是直接對prop的屬性直接賦值,依然會出現報錯。ui
事實上,.sync
修飾符是一個簡寫,它作了一件事情this
<template>
<children :msg.sync="parentMsg"></children>
<!-- 等價於 -->
<children :msg="parentMsg" @update:msg="parentMsg = $event"></children>
<!-- 這裏的$event就是子組件$emit傳遞的參數 -->
</template>
複製代碼
當須要把一個對象中的屬性所有經過.sync
傳入雙向數據流時,能夠再簡便一下寫法spa
<template>
<children :.sync="obj"></children>
</template>
<script> export default{ components:{ children }, data(){ return{ obj:{ parentMsg:'test' } } } } </script>
複製代碼
當使用這種寫法時,會將obj對象中的全部屬性都經過獨立的props傳遞給子組件,並監聽對應的update:
,此時在子組件中也要聲明對應的props。雙向綁定
在父子組件中,使用雙向數據流,在某些時候,可以起到很好效果,以及開發體驗,不過必定要適量使用,雙向數據流會給項目的後期維護增長負擔。
tips:懂得分享纔會走得更遠。
歡迎來個人Vue技術羣交流:887516034
若是以爲對你有用,就打賞一下吧。