vue之父子組件間通信實(shí)例講解(props、$ref 、 $emit )

組件是 vue.js 最強(qiáng)大的功能之一,而組件實(shí)例的作用域是相互獨(dú)立的,這就意味著不同組件之間的數(shù)據(jù)無(wú)法相互引用。那么組件間如何通信,也就成為了vue中重點(diǎn)知識(shí)了。這篇文章將會(huì)通過(guò)props、$ref和 $emit 這幾個(gè)知識(shí)點(diǎn),來(lái)講解如何實(shí)現(xiàn)父子組件間通信。

在說(shuō)如何實(shí)現(xiàn)通信之前,我們先來(lái)建兩個(gè)組件father.vue和child.vue作為示例的基礎(chǔ)。

//父組件

<template>
  <div>
    <h1>我是父組件!</h1>
    <child></child>
  </div>
</template>

<script>
import Child from '../components/child.vue'
export default {
  components: {Child},
}
</script>

//子組件

<template>
  <h3>我是子組件!</h3>
</template>

<script>
</script>

這兩部分的代碼都很清晰明了,父組件通過(guò)import的方式導(dǎo)入子組件,并在components屬性中注冊(cè),然后子組件就可以用標(biāo)簽<child>的形式嵌進(jìn)父組件了。運(yùn)行father.vue后的效果是這樣的:


示例效果一

1.通過(guò)prop實(shí)現(xiàn)通信

子組件的props選項(xiàng)能夠接收來(lái)自父組件數(shù)據(jù)。沒(méi)錯(cuò),僅僅只能接收,props是單向綁定的,即只能父組件向子組件傳遞,不能反向。而傳遞的方式也分為兩種:

(1)靜態(tài)傳遞

子組件通過(guò)props選項(xiàng)來(lái)聲明一個(gè)自定義的屬性,然后父組件就可以在嵌套標(biāo)簽的時(shí)候,通過(guò)這個(gè)屬性往子組件傳遞數(shù)據(jù)了。

 <!-- 父組件 -->

<template>
  <div>
    <h1>我是父組件!</h1>
    <child message="我是子組件一!"></child>  //通過(guò)自定義屬性傳遞數(shù)據(jù)
  </div>
</template>

<script>
import Child from '../components/child.vue'
export default {
  components: {Child},
}
</script>
 <!-- 子組件 -->

<template>
  <h3>{{message}}</h3>
</template>
<script>
  export default {
    props: ['message']   //聲明一個(gè)自定義的屬性
  }
</script>

(2)動(dòng)態(tài)傳遞

我們已經(jīng)知道了可以像上面那樣給 props 傳入一個(gè)靜態(tài)的值,但是我們更多的情況需要?jiǎng)討B(tài)的數(shù)據(jù)。這時(shí)候就可以用 v-bind 來(lái)實(shí)現(xiàn)。通過(guò)v-bind綁定props的自定義的屬性,傳遞去過(guò)的就不是靜態(tài)的字符串了,它可以是一個(gè)表達(dá)式、布爾值、對(duì)象等等任何類型的值。

 <!-- 父組件 -->

<template>
  <div>
    <h1>我是父組件!</h1>
    <child message="我是子組件一!"></child> 

    <!-- 這是一個(gè) JavaScript 表達(dá)式而不是一個(gè)字符串。-->
    <child v-bind:message="a+b"></child>

    <!-- 用一個(gè)變量進(jìn)行動(dòng)態(tài)賦值。-->
    <child v-bind:message="msg"></child>
  </div>
</template>

<script>
import Child from '../components/child.vue'
export default {
  components: {Child},
  data() {
    return {
      a:'我是子組件二!',
      b:112233,
      msg: '我是子組件三!'+ Math.random()
    }
  }
}
</script>
 <!-- 子組件 -->

<template>
  <h3>{{message}}</h3>
</template>
<script>
  export default {
    props: ['message']
  }
</script>

出來(lái)的效果是這樣的:


示例效果二

2.通過(guò)$ref 實(shí)現(xiàn)通信

對(duì)于ref官方的解釋是:ref 是被用來(lái)給元素或子組件注冊(cè)引用信息的。引用信息將會(huì)注冊(cè)在父組件的 $refs 對(duì)象上。
看不懂對(duì)吧?很正常,我也看不懂。那應(yīng)該怎么理解?看看我的解釋:

  • 如果ref用在子組件上,指向的是組件實(shí)例,可以理解為對(duì)子組件的索引,通過(guò)$ref可能獲取到在子組件里定義的屬性和方法。
  • 如果ref在普通的 DOM 元素上使用,引用指向的就是 DOM 元素,通過(guò)$ref可能獲取到該DOM 的屬性集合,輕松訪問(wèn)到DOM元素,作用與JQ選擇器類似。

那如何通過(guò)$ref 實(shí)現(xiàn)通信?下面我將上面prop實(shí)現(xiàn)的功能,用$ref實(shí)現(xiàn)一遍:

 <!-- 父組件 -->

<template>
  <div>
    <h1>我是父組件!</h1>
    <child ref="msg"></child>
  </div>
</template>

<script>
  import Child from '../components/child.vue'
  export default {
    components: {Child},
    mounted: function () {
      console.log( this.$refs.msg);
      this.$refs.msg.getMessage('我是子組件一!')
    }
  }
</script>
 <!-- 子組件 -->

<template>
  <h3>{{message}}</h3>
</template>
<script>
  export default {
    data(){
      return{
        message:''
      }
    },
    methods:{
      getMessage(m){
        this.message=m;
      }
    }
  }
</script>

從上面的代碼我們可以發(fā)現(xiàn),通過(guò)ref=‘msg’可以將子組件child的實(shí)例指給$ref,并且通過(guò).msg.getMessage()調(diào)用到子組件的getMessage方法,將參數(shù)傳遞給子組件。下面是“ console.log( this.$refs.msg);”打印出來(lái)的內(nèi)容,這可以讓大家更加了解,究竟通過(guò)ref我們獲取了什么:


console.log

最后的效果是這樣的:


示例效果三
這里再補(bǔ)充一點(diǎn)就是,prop和$ref之間的區(qū)別:
  • prop 著重于數(shù)據(jù)的傳遞,它并不能調(diào)用子組件里的屬性和方法。像創(chuàng)建文章組件時(shí),自定義標(biāo)題和內(nèi)容這樣的使用場(chǎng)景,最適合使用prop。
  • $ref 著重于索引,主要用來(lái)調(diào)用子組件里的屬性和方法,其實(shí)并不擅長(zhǎng)數(shù)據(jù)傳遞。而且ref用在dom元素的時(shí)候,能使到選擇器的作用,這個(gè)功能比作為索引更常有用到。

3.通過(guò)$emit 實(shí)現(xiàn)通信

上面兩種示例主要都是父組件向子組件通信,而通過(guò)$emit 實(shí)現(xiàn)子組件向父組件通信。
對(duì)于$emit官網(wǎng)上也是解釋得很朦朧,我按我自己的理解是這樣的:
vm.$emit( event, arg )
$emit 綁定一個(gè)自定義事件event,當(dāng)這個(gè)這個(gè)語(yǔ)句被執(zhí)行到的時(shí)候,就會(huì)將參數(shù)arg傳遞給父組件,父組件通過(guò)@event監(jiān)聽(tīng)并接收參數(shù)。

<template>
  <div>
    <h1>{{title}}</h1>
    <child @getMessage="showMsg"></child>
  </div>
</template>

<script>
  import Child from '../components/child.vue'
  export default {
    components: {Child},
    data(){
      return{
        title:''
      }
    },
    methods:{
      showMsg(title){
       this.title=title;
      }
  }
  }
</script>

<template>
  <h3>我是子組件!</h3>
</template>
<script>
  export default {
    mounted: function () {
      this.$emit('getMessage', '我是父組件!')
    }
  }
</script>
示例效果三
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,443評(píng)論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,530評(píng)論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事?!?“怎么了?”我有些...
    開(kāi)封第一講書人閱讀 176,407評(píng)論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 62,981評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,759評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 55,204評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,263評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 42,415評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,955評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,782評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,983評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,222評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 34,650評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 35,892評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,675評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,967評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容

  • 此文基于官方文檔,里面部分例子有改動(dòng),加上了一些自己的理解 什么是組件? 組件(Component)是 Vue.j...
    陸志均閱讀 3,839評(píng)論 5 14
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容。關(guān)于...
    云之外閱讀 5,067評(píng)論 0 29
  • Vue 實(shí)例 屬性和方法 每個(gè) Vue 實(shí)例都會(huì)代理其 data 對(duì)象里所有的屬性:var data = { a:...
    云之外閱讀 2,231評(píng)論 0 6
  • 我的小店
    axlsjy閱讀 204評(píng)論 0 0
  • 看影片《歡樂(lè)好聲音》,總能感覺(jué)到一種人性的熱烈與奔放。那酷酷的音樂(lè),斑斕的畫面,給人震撼的同時(shí),亦激蕩起內(nèi)心沉睡已...
    風(fēng)落雨開(kāi)Q閱讀 200評(píng)論 0 0