Vue父子組件通信和雙向綁定

本篇文章主要介紹父子組件傳值,組件的數據雙向綁定鹃觉。

1. 基礎父子組件傳值

父子組件傳值,這是Vue組件傳值最常見睹逃,最基礎的傳值方法盗扇。
父組件向子組件傳值使用Props,子組件定義期望接收傳值的名字、類型沉填、默認值等等疗隶,父組件Props值的改變會自動同步到子組件。
子組件向父組件傳值使用事件觸發(fā),即使用$emit注冊事件翼闹,在父組件觸發(fā)斑鼻,這個事件可以攜帶值,而且一個事件的觸發(fā)本身就是在傳遞信息橄碾。
代碼實現:

//父組件
<template>
  <div id="parent">
  父組件的text:{{text}}
    <Child :text="text" @changeText="prentEvent"></Child>
  </div>
</template>
<script>
export default {
  components: {
    Child: () => import('@/components/Child')
   },
  data() {
    return {
      text: 'a'
    }
  },
  methods: {
    prentEvent(value) {
      this.text = value
    },
}
</script>
//子組件
<template>
  <div class="child">
    <p>子組件text:{{text}}</p>
    <button @click="changeParent">改變父組件text</button>
  </div>
</template> 
<script>
export default {
  name: 'Child',
  props: {
    text: {
      type: String,
      required: true
    }
  },
  data() {
    return {}
  },
  methods: {
    changeParent() {
      this.$emit('changeText', 'b')
    },
  },
}
</script>
1.gif

由于父組件的Props改變會自動傳遞到子組件卵沉,所以會同步變化。

2. 父子組件傳值的雙向綁定

上述例子有點雙向綁定的意思法牲,但這并不是雙向綁定,Vue的數據都是單向流動的琼掠,而且Vue中從來就沒有任何的雙向綁定拒垃,那些雙向綁定只是語法糖而已
我們都知道v-model可以用在 input標簽上瓷蛙,實現雙向綁定悼瓮,其實Vue已經把input標簽進行了修改,也就是 input標簽已經是一個Vue的內置組件了艰猬,同樣的內置組件還有很多横堡,比如,用于緩存的keep-alive,用于路由鏈接的router-like冠桃,用于路由視圖展示的router-view等等命贴。
實現一個自定組件的v-model之前,我們先實現一個雙向綁定食听,代碼如下:

//Com1
<template>
  <div class="com1">
    Com1:
    <input type="text" :value="value" @input="changeSelf" />
    <Com2 :value="value" @input="changes"></Com2>
  </div>
</template>
<script>
export default {
  name: 'Com1',
  components: {
    Com2: () => import('./Com2')
  },
  data() {
    return {
      value: ''
    }
  },
  methods: {
    changes(values) {
      this.value = values
    },
    changeSelf(e) {
      this.value = e.target.value;
    },
  },
}
</script>
//Com2
<template>
  <div class="com2">
    Com2:
    <input type="text" :value="value" @input="Com2Input" />
  </div>
</template>
<script>
export default {
  name: 'Com2',
  props: {
    value: {
      type: String,
      required: true,
    }
  },
  methods: {
    Com2Input(e) {
      this.$emit('input', e.target.value)
    }
  },
}
</script>

2.gif

我們沒用Vue的v-model同樣可以實現數據的雙向綁定胸蛛。我們如何改造成v-model呢?只能改變父組件Com1樱报,子組件不能更改葬项,代碼如下:

//Com1
<template>
  <div class="com1">
    Com1:
    <!--下面這行改變是為了精簡代碼,使用input標簽的v-model--!>
    <!-- <input type="text" :value="value" @input="changeSelf" /> -->
    <input type="text" v-model="value" />
    <!-- <Com2 :value="value" @input="changes"></Com2> -->
    <Com2 v-model="value"></Com2>
  </div>
</template>
<script>
export default {
  name: 'Com1',
  components: {
    Com2: () => import('./Com2')
  },
  data() {
    return {
      value: ''
    }
  },
  methods: {
    // changes(values) {
    //   this.value = values
    // },
    // changeSelf(e) {
    //   this.value = e.target.value;
    // },
  },
}
</script>
3.gif

由此我們實現了Com2這個組件的v-model,改變的是取消了Com2的事件監(jiān)聽@input,Propsvalue迹蛤,換來了v-model民珍,這個簡化的過程就是語法糖襟士。v-model會自動處理那些注釋掉的操作,即v-model會自動處理一個組件的input事件和valueProps嚷量,讓兩者綁定陋桂。
input的v-model已經實現,我們來說一說自定義組件的v-model津肛,v-model會檢測組件的input事件和valueProps章喉,這顯然是不行的,自定義組件需要的不一定是這兩個東西,幸好子組件里還有一個屬性mode身坐,可以用來改變v-model默認監(jiān)聽的Props和event秸脱,代碼如下:

export default {
  name: 'Com2',
  model: {
    //默認監(jiān)聽的事件和prop
    // event: 'input',
    // prop: 'value',
    //自定義的監(jiān)聽子組件觸發(fā)事件和傳進去的prop
    event: 'change',
    prop: 'datas'
  },
  //其他代碼
}

這時在父組件使用子組件的時候,在子組件使用v-model就會自動處理change事件和datasProps部蛇,這樣就可以隨意定義想要的雙向綁定屬性了摊唇,但是一個組件只能有一個v-model
在Vue 2.3.0 中加入了.sync 修飾符涯鲁,也是用來處理雙向綁定的巷查,封裝流程和v-model類似,在子組件需要這樣操作抹腿,代碼如下:

//在需注冊事件的地方這樣寫
this.$emit('update:datas', newDatas)
//在父組件調用這個子組件的時候這樣寫
<Com3
  v-bind:datas="datas"
  v-on:update:datas="datas = $event"
></Com3>
//使用.sync 修飾符簡化為
<Com3 :datas.sync="datas"></Com3>
//子組件的事件注冊不改動

這樣同樣可以實現雙向綁定岛请,一個組件可以有多個.sync修飾符雙向綁定。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末警绩,一起剝皮案震驚了整個濱河市崇败,隨后出現的幾起案子,更是在濱河造成了極大的恐慌肩祥,老刑警劉巖后室,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異混狠,居然都是意外死亡岸霹,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門将饺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贡避,“玉大人,你說我怎么就攤上這事俯逾∶惩埃” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵桌肴,是天一觀的道長皇筛。 經常有香客問我,道長坠七,這世上最難降的妖魔是什么水醋? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任旗笔,我火速辦了婚禮,結果婚禮上拄踪,老公的妹妹穿的比我還像新娘蝇恶。我一直安慰自己,他們只是感情好惶桐,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布撮弧。 她就那樣靜靜地躺著,像睡著了一般姚糊。 火紅的嫁衣襯著肌膚如雪贿衍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天救恨,我揣著相機與錄音贸辈,去河邊找鬼。 笑死肠槽,一個胖子當著我的面吹牛擎淤,可吹牛的內容都是我干的。 我是一名探鬼主播秸仙,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼嘴拢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了寂纪?” 一聲冷哼從身側響起炊汤,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弊攘,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體姑曙,經...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡襟交,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了伤靠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捣域。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖宴合,靈堂內的尸體忽然破棺而出焕梅,到底是詐尸還是另有隱情,我是刑警寧澤卦洽,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布贞言,位于F島的核電站,受9級特大地震影響阀蒂,放射性物質發(fā)生泄漏该窗。R本人自食惡果不足惜弟蚀,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望酗失。 院中可真熱鬧义钉,春花似錦、人聲如沸规肴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拖刃。三九已至删壮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間序调,已是汗流浹背醉锅。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留发绢,地道東北人硬耍。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像边酒,于是被迫代替她去往敵國和親经柴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內容

  • 組件(Component)是Vue.js最核心的功能墩朦,也是整個架構設計最精彩的地方坯认,當然也是最難掌握的。...
    六個周閱讀 5,587評論 0 32
  • vue概述 在官方文檔中氓涣,有一句話對Vue的定位說的很明確:Vue.js 的核心是一個允許采用簡潔的模板語法來聲明...
    li4065閱讀 7,193評論 0 25
  • 一牛哺、了解Vue.js 1.1.1 Vue.js是什么? 簡單小巧劳吠、漸進式引润、功能強大的技術棧 1.1.2 為什么學習...
    蔡華鵬閱讀 3,317評論 0 3
  • VUE介紹 Vue的特點構建用戶界面,只關注View層簡單易學痒玩,簡潔淳附、輕量、快速漸進式框架 框架VS庫庫蠢古,是一封裝...
    多多醬_DuoDuo_閱讀 2,692評論 1 17
  • Vue 實例 屬性和方法 每個 Vue 實例都會代理其 data 對象里所有的屬性:var data = { a:...
    云之外閱讀 2,204評論 0 6