Vue父子組件如何雙向綁定傳值

前言

父子組件之間的雙向綁定很是簡單,可是不少人由於是從Vue 2+開始使用的,可能不知道如何雙向綁定,固然最簡單的雙向綁定(單文件中)就是表單元素的v-model了,例如<input type="text" />它會響應表單元素的value屬性,當輸入框文本改變時,會將value值傳給v-model所綁定的變量,若是同時設置v-modelvaluevalue屬性無效。javascript

歡迎來個人Vue技術羣交流:Vue887516034html

父子組件的自定義雙向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技術羣交流:Vue887516034

若是以爲對你有用,就打賞一下吧。

相關文章
相關標籤/搜索