Vue組件間通信方式都有哪些?

一江兢、組件間通信的概念

開始之前晕窑,我們把組件間通信這個詞進行拆分

  • 組件
  • 通信

都知道組件是vue最強大的功能之一坤次,vue中每一個.vue我們都可以視之為一個組件通信指的是發(fā)送者通過某種媒體以某種格式來傳遞信息到收信者以達到某個目的凿可。廣義上掰曾,任何信息的交通都是通信組件間通信即指組件(.vue)通過某種方式來傳遞信息以達到某個目的舉個栗子我們在使用UI框架中的table組件,可能會往table組件中傳入某些數(shù)據(jù)倘是,這個本質(zhì)就形成了組件之間的通信

二亭枷、組件間通信解決了什么

在古代,人們通過驛站搀崭、飛鴿傳書叨粘、烽火報警、符號瘤睹、語言升敲、眼神、觸碰等方式進行信息傳遞轰传,到了今天驴党,隨著科技水平的飛速發(fā)展,通信基本完全利用有線或無線電完成获茬,相繼出現(xiàn)了有線電話港庄、固定電話、無線電話恕曲、手機鹏氧、互聯(lián)網(wǎng)甚至視頻電話等各種通信方式從上面這段話,我們可以看到通信的本質(zhì)是信息同步佩谣,共享回到vue中把还,每個組件之間的都有獨自的作用域,組件間的數(shù)據(jù)是無法共享的但實際開發(fā)工作中我們常常需要讓組件之間共享數(shù)據(jù),這也是組件通信的目的要讓它們互相之間能進行通訊笨篷,這樣才能構(gòu)成一個有機的完整系統(tǒng)

二瞳秽、組件間通信的分類

組件間通信的分類可以分成以下

  • 父子組件之間的通信
  • 兄弟組件之間的通信
  • 祖孫與后代組件之間的通信
  • 非關(guān)系組件間之間的通信

關(guān)系圖:

1.png

三、組件間通信的方案

整理vue中8種常規(guī)的通信方案

  1. 通過 props 傳遞
  2. 通過 $emit 觸發(fā)自定義事件
  3. 使用 ref
  4. EventBus
  5. parent 或root
  6. attrs 與 listeners
  7. Provide 與 Inject
  8. Vuex

props傳遞數(shù)據(jù)

  • 適用場景:父組件傳遞數(shù)據(jù)給子組件
  • 子組件設(shè)置props屬性率翅,定義接收父組件傳遞過來的參數(shù)
  • 父組件在使用子組件標簽中通過字面量來傳遞值

Children.vue

props:{  
    // 字符串形式  
 name:String // 接收的類型參數(shù)  
    // 對象形式  
    age:{    
        type:Number, // 接收的類型為數(shù)值  
        defaule:18,  // 默認值為18  
       require:true // age屬性必須傳遞  
    }  
}  

Father.vue組件

<Children name="jack" age=18 />  

$emit 觸發(fā)自定義事件

  • 適用場景:子組件傳遞數(shù)據(jù)給父組件
  • 子組件通過$emit觸發(fā)自定義事件练俐,$emit第二個參數(shù)為傳遞的數(shù)值
  • 父組件綁定監(jiān)聽器獲取到子組件傳遞過來的參數(shù)

Chilfen.vue

this.$emit('add', good)  

Father.vue

<Children @add="cartAdd($event)" />  

ref

  • 父組件在使用子組件的時候設(shè)置ref
  • 父組件通過設(shè)置子組件ref來獲取數(shù)據(jù)

父組件

<Children ref="foo" />  

this.$refs.foo  // 獲取子組件實例,通過子組件實例我們就能拿到對應的數(shù)據(jù)  

EventBus

  • 使用場景:兄弟組件傳值
  • 創(chuàng)建一個中央時間總線EventBus
  • 兄弟組件通過$emit觸發(fā)自定義事件冕臭,$emit第二個參數(shù)為傳遞的數(shù)值
  • 另一個兄弟組件通過$on監(jiān)聽自定義事件

Bus.js

// 創(chuàng)建一個中央時間總線類  
class Bus {  
  constructor() {  
    this.callbacks = {};   // 存放事件的名字  
  }  
  $on(name, fn) {  
    this.callbacks[name] = this.callbacks[name] || [];  
    this.callbacks[name].push(fn);  
  }  
  $emit(name, args) {  
    if (this.callbacks[name]) {  
      this.callbacks[name].forEach((cb) => cb(args));  
    }  
  }  
}  

// main.js  
Vue.prototype.$bus = new Bus() // 將$bus掛載到vue實例的原型上  
// 另一種方式  
Vue.prototype.$bus = new Vue() // Vue已經(jīng)實現(xiàn)了Bus的功能  

Children1.vue

this.$bus.$emit('foo')  

Children2.vue

this.$bus.$on('foo', this.handle)  

parent 或 root

  • 通過共同祖輩$parent或者$root搭建通信僑聯(lián)

兄弟組件

this.$parent.on('add',this.add)

另一個兄弟組件

this.$parent.emit('add')

attrs 與 listeners

  • 適用場景:祖先傳遞數(shù)據(jù)給子孫
  • 設(shè)置批量向下傳屬性$attrs$listeners
  • 包含了父級作用域中不作為 prop 被識別 (且獲取) 的特性綁定 ( class 和 style 除外)腺晾。
  • 可以通過 v-bind="$attrs" 傳?內(nèi)部組件
// child:并未在props中聲明foo  
<p>{{$attrs.foo}}</p>  

// parent  
<HelloWorld foo="foo"/>  
// 給Grandson隔代傳值,communication/index.vue  
<Child2 msg="lalala" @some-event="onSomeEvent"></Child2>  

// Child2做展開  
<Grandson v-bind="$attrs" v-on="$listeners"></Grandson>  

// Grandson使?  
<div @click="$emit('some-event', 'msg from grandson')">  
{{msg}}  
</div>  

provide 與 inject

  • 在祖先組件定義provide屬性辜贵,返回傳遞的值
  • 在后代組件通過inject接收組件傳遞過來的值

祖先組件

provide(){  
    return {  
        foo:'foo'  
    }  
}  

后代組件

inject:['foo'] // 獲取到祖先組件傳遞過來的值  

vuex

  • 適用場景: 復雜關(guān)系的組件數(shù)據(jù)傳遞

  • Vuex作用相當于一個用來存儲共享變量的容器

    2.png

  • state用來存放共享變量的地方

  • getter悯蝉,可以增加一個getter派生狀態(tài),(相當于store中的計算屬性)托慨,用來獲得共享變量的值

  • mutations用來存放修改state的方法鼻由。

  • actions也是用來存放修改state的方法,不過action是在mutations的基礎(chǔ)上進行厚棵。常用來做一些異步操作

小結(jié)

  • 父子關(guān)系的組件數(shù)據(jù)傳遞選擇 props$emit進行傳遞蕉世,也可選擇ref
  • 兄弟關(guān)系的組件數(shù)據(jù)傳遞可選擇$bus,其次可以選擇$parent進行傳遞
  • 祖先與后代組件數(shù)據(jù)傳遞可選擇attrslisteners或者 ProvideInject
  • 復雜關(guān)系的組件數(shù)據(jù)傳遞可以通過vuex存放共享的變量
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末婆硬,一起剝皮案震驚了整個濱河市狠轻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌彬犯,老刑警劉巖向楼,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異谐区,居然都是意外死亡湖蜕,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進店門卢佣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來重荠,“玉大人箭阶,你說我怎么就攤上這事虚茶。” “怎么了仇参?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵嘹叫,是天一觀的道長。 經(jīng)常有香客問我诈乒,道長罩扇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮喂饥,結(jié)果婚禮上消约,老公的妹妹穿的比我還像新娘。我一直安慰自己员帮,他們只是感情好或粮,可當我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捞高,像睡著了一般氯材。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上硝岗,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天氢哮,我揣著相機與錄音,去河邊找鬼型檀。 笑死冗尤,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的胀溺。 我是一名探鬼主播生闲,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼月幌!你這毒婦竟也來了碍讯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤扯躺,失蹤者是張志新(化名)和其女友劉穎捉兴,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體录语,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡倍啥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了澎埠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虽缕。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蒲稳,靈堂內(nèi)的尸體忽然破棺而出氮趋,到底是詐尸還是另有隱情,我是刑警寧澤江耀,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布剩胁,位于F島的核電站,受9級特大地震影響祥国,放射性物質(zhì)發(fā)生泄漏昵观。R本人自食惡果不足惜晾腔,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望啊犬。 院中可真熱鬧灼擂,春花似錦、人聲如沸觉至。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽康谆。三九已至领斥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沃暗,已是汗流浹背月洛。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留孽锥,地道東北人嚼黔。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像惜辑,于是被迫代替她去往敵國和親唬涧。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,860評論 2 361

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