元件通訊
幾乎所有的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後,走一遍給出的小示例。但是如果你的專案並不複雜的話,可以不考慮狀態管理,那麼什麼時候需要使用狀態管理呢?
我們來看這樣一個佈局
如果component1中的某個資料變更,那麼com2,com3也要跟著更新,此時com3中又細分為了三個小元件。
問題:
- 多個試圖依賴同一個狀態
- 多層巢狀的元件,資料變更和程式碼維護困難
那這樣的情況時,我們可以考慮使用狀態管理。下一篇文章將詳細講解關於vuex的實踐和理解。
寫在最後的總結
總結方法很簡單,網上教程也很多,最重要的是要結合自己的實踐去感悟,這樣才能有收穫,有成長。
Cayley 一個不斷努力學習的女程式設計師