Vue組件通訊實踐記錄

組件通訊

幾乎全部的mvvm框架中都要涉及組件通訊的功能(吐槽一下knockout,畢竟是鼻祖就先不說它了)。並且目前的前端形式來看,組件化是一個項目的基礎。因此選好一個合適的框架後,隨着組件的不斷增長,業務的複雜度提高,組件之間的通訊變得尤其重要。javascript

實踐方法

因爲更換新的框架,咱們的項目由Avalon更新成Vue.可是爲了兼容之前的業務代碼,不能直接使用vue的標準實踐方式,我仍是拿過來後封裝了一個vue的class,具體業務裏面不影響使用,封裝的過程以後寫出來再聊吧,下面來總結一下最近用到的通訊實踐方法。html

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

Vue.component('book-component', {
  template: tpl,//能夠傳進來子組件的模板文件
  props: ['book'],
  data: function () {
    return { myBook: this.bookdata }
  }
})

複製代碼

建議接收到單向的props數據後,定義一個局部變量來初始化使用。java

2.父組件與子組件之間通訊的其餘方式

vue中給實例提供了三個咱們可用的API$children$refs以及$parentnode

$children:當前實例的直接子組件。須要注意 $children 並不保證順序,也不是響應式的。程序員

$refs:包含了當前實例全部擁有 ref 註冊的子組件的對象.vuex

$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後,走一遍給出的小示例。可是若是你的項目並不複雜的話,能夠不考慮狀態管理,那麼何時須要使用狀態管理呢?

咱們來看這樣一個佈局

若是component1中的某個數據變動,那麼com2,com3也要跟着更新,此時com3中又細分爲了三個小組件。

問題:

  1. 多個試圖依賴同一個狀態
  2. 多層嵌套的組件,數據變動和代碼維護困難

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

寫在最後的總結

總結方法很簡單,網上教程也不少,最重要的是要結合本身的實踐去感悟,這樣纔能有收穫,有成長。

Cayley 一個不斷努力學習的女程序員

相關文章
相關標籤/搜索