面試官:Vue組件間通訊方式都有哪些?

1、組件間通訊的概念

開始以前,咱們把組件間通訊這個詞進行拆分vue

  • 組件
  • 通訊

都知道組件是vue最強大的功能之一,vue中每個.vue咱們均可以視之爲一個組件vuex

通訊指的是發送者經過某種媒體以某種格式來傳遞信息到收信者以達到某個目的。廣義上,任何信息的交通都是通訊框架

組件間通訊即指組件(.vue)經過某種方式來傳遞信息以達到某個目的異步

舉個栗子ide

咱們在使用UI框架中的table組件,可能會往table組件中傳入某些數據,這個本質就造成了組件之間的通訊post

2、組件間通訊解決了什麼

在古代,人們經過驛站、飛鴿傳書、烽火報警、符號、語言、眼神、觸碰等方式進行信息傳遞,到了今天,隨着科技水平的飛速發展,通訊基本徹底利用有線或無線電完成,相繼出現了有線電話、固定電話、無線電話、手機、互聯網甚至視頻電話等各類通訊方式ui

從上面這段話,咱們能夠看到通訊的本質是信息同步,共享this

回到vue中,每一個組件之間的都有獨自的做用域,組件間的數據是沒法共享的spa

但實際開發工做中咱們經常須要讓組件之間共享數據,這也是組件通訊的目的prototype

要讓它們互相之間能進行通信,這樣才能構成一個有機的完整系統

2、組件間通訊的分類

組件間通訊的分類能夠分紅如下

  • 父子組件之間的通訊
  • 兄弟組件之間的通訊
  • 祖孫與後代組件之間的通訊
  • 非關係組件間之間的通訊

關係圖:

## 3、組件間通訊的方案

整理vue中8種常規的通訊方案

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

### props傳遞數據

  • 適用場景:父組件傳遞數據給子組件
  • 子組件設置props屬性,定義接收父組件傳遞過來的參數
  • 父組件在使用子組件標籤中經過字面量來傳遞值

Children.vue

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

Father.vue組件

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

### $emit觸發自定義事件

  • 適用場景:子組件傳遞數據給父組件
  • 子組件經過$emit觸發自定義事件,$emit第二個參數爲傳遞的數值
  • 父組件綁定監聽器獲取到子組件傳遞過來的參數

Chilfen.vue

this.$emit('add', good)

Father.vue

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

### ref

  • 父組件在使用子組件的時候設置ref
  • 父組件經過設置子組件ref來獲取數據

父組件

<Children ref="foo" />

this.$refs.foo  // 獲取子組件實例,經過子組件實例咱們就能拿到對應的數據

### EventBus

  • 使用場景:兄弟組件傳值
  • 建立一箇中央時間總線EventBus
  • 兄弟組件經過$emit觸發自定義事件,$emit第二個參數爲傳遞的數值
  • 另外一個兄弟組件經過$on監聽自定義事件

Bus.js

// 建立一箇中央時間總線類
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已經實現了Bus的功能

Children1.vue

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

Children2.vue

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

### $parent 或 $root

  • 經過共同祖輩$parent或者$root搭建通訊僑聯

兄弟組件

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

另外一個兄弟組件

this.$parent.emit('add')

### $attrs 與 $listeners

  • 適用場景:祖先傳遞數據給子孫
  • 設置批量向下傳屬性$attrs$listeners
  • 包含了父級做用域中不做爲 prop 被識別 (且獲取) 的特性綁定 ( class 和 style 除外)。
  • 能夠經過 v-bind="$attrs" 傳⼊內部組件

    // 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

  • 適用場景: 複雜關係的組件數據傳遞
  • Vuex做用至關於一個用來存儲共享變量的容器

  • state用來存放共享變量的地方
  • getter,能夠增長一個getter派生狀態,(至關於store中的計算屬性),用來得到共享變量的值
  • mutations用來存放修改state的方法。
  • actions也是用來存放修改state的方法,不過action是在mutations的基礎上進行。經常使用來作一些異步操做

### 小結

  • 父子關係的組件數據傳遞選擇 props$emit進行傳遞,也可選擇ref
  • 兄弟關係的組件數據傳遞可選擇$bus,其次能夠選擇$parent進行傳遞
  • 祖先與後代組件數據傳遞可選擇attrslisteners或者 ProvideInject
  • 複雜關係的組件數據傳遞能夠經過vuex存放共享的變量

## 參考文獻

@JS語音社羣
相關文章
相關標籤/搜索