Vue元件通訊實踐記錄

cayley的程式設計之路發表於2017-08-15

元件通訊

幾乎所有的mvvm框架中都要涉及元件通訊的功能(吐槽一下knockout,畢竟是鼻祖就先不說它了)。而且目前的前端形式來看,元件化是一個專案的基礎。所以選好一個合適的框架後,隨著元件的不斷增加,業務的複雜度提升,元件之間的通訊變得尤為重要。

實踐方法

由於更換新的框架,我們的專案由Avalon更新成Vue.但是為了相容以前的業務程式碼,不能直接使用vue的標準實踐方式,我還是拿過來後封裝了一個vue的class,具體業務裡面不影響使用,封裝的過程之後寫出來再聊吧,下面來總結一下最近用到的通訊實踐方法。

1.父元件是通過props傳遞資料給子元件

vmodel 中包含了兩個子元件

<div class="w-base">
    <book-component v-bind:bookdata="book"></book-component>
</div>

<div class="base">
    <node-component v-bind:catalog="catalog" ></node-component>
</div>

複製程式碼

在上面這段程式碼中我們可以看到,定義了兩個子元件,並且使用指定v-bind指令傳遞了資料,子元件會接收到傳遞的資料。

Vue.component('book-component', {
  template: tpl,//可以傳進來子元件的模板檔案
  props: ['book'],
  data: function () {
    return { myBook: this.bookdata }
  }
})

複製程式碼

建議接收到單向的props資料後,定義一個區域性變數來初始化使用。

2.父元件與子元件之間通訊的其他方式

vue中給例項提供了三個我們可用的API$children$refs以及$parent

$children:當前例項的直接子元件。需要注意 $children 並不保證順序,也不是響應式的。

$refs:包含了當前例項所有擁有 ref 註冊的子元件的物件.

$parent: 當前例項的父例項。

所以說,如果在通訊方面我們我元件想要呼叫子元件,能用的方法只有$refs了,因為$children是一個陣列,並且不保證順序,也沒有相關的id去尋找我們需要的那個特定子元件。但是如果使用$refs去尋找特定子元件,那就必須要給那個子元件註冊ref

父元件的模版

<!-- vm.$refs.child will be the child comp instance -->
<child-component ref="child"></child-comp>
複製程式碼

父元件

//找到子元件並且呼叫它的方法
var myChild = this.$refs.child;
myChild.func();
複製程式碼

子元件

//找到父元件並且呼叫它的方法
var myParent = this.$parent;
myParent.func();
複製程式碼

3.平行元件之間的兩種通訊方式

a.官方提供的事件bus

var bus = new Vue()
// 觸發元件 A 中的事件
bus.$emit('id-selected', 1)
// 在元件 B 建立的鉤子中監聽事件
bus.$on('id-selected', function (id) {
  // ...
})
複製程式碼

b.通過父元件去找兄弟元件

//找到父元件的$refs物件,然後找到元件的兄弟元件
 var $refs = this.$parent?this.$parent.$refs:{};
 var childComponent =  $refs.child; //child為改元件的ref屬性值
複製程式碼

其實以上兩種方法最好的實踐方式是封裝到專案的基類中,這樣不用每次都去定義一個空Vue()例項,而是每個例項的基類中都有這個事件bus。同樣可以封裝找到其他兄弟元件的方法,但是該兄弟元件必須註冊ref

下面這個方法是我在專案中封裝的用於找到父元件,然後再去找到兄弟元件的方法。

//平行元件之間的通訊
getComponentByRef: function(refId) {
    var $refs = this.$parent?this.$parent.$refs:{};
    for (var $id in $refs) {
        if ($id == refId) {
            return $refs[$id];
        }
    }
    return null;
}
複製程式碼

使用

//在元件中直接使用
this.getComponentByRef("booknode").updateNode(this.node);
複製程式碼

4.元件間複雜資料通訊Vuex

一說到vuex,很多剛開始接觸vue的人會主動避免去使用它,其實它並沒有想象中的那麼複雜。最好的開始是引入vuex後,走一遍給出的小示例。但是如果你的專案並不複雜的話,可以不考慮狀態管理,那麼什麼時候需要使用狀態管理呢?

我們來看這樣一個佈局

Vue元件通訊實踐記錄

如果component1中的某個資料變更,那麼com2,com3也要跟著更新,此時com3中又細分為了三個小元件。

問題:

  1. 多個試圖依賴同一個狀態
  2. 多層巢狀的元件,資料變更和程式碼維護困難

那這樣的情況時,我們可以考慮使用狀態管理。下一篇文章將詳細講解關於vuex的實踐和理解。

寫在最後的總結

總結方法很簡單,網上教程也很多,最重要的是要結合自己的實踐去感悟,這樣才能有收穫,有成長。

Cayley 一個不斷努力學習的女程式設計師

相關文章