Vue 組件間通訊方式

例子是在 jsrun.net 平臺編寫,不支持移動端平臺,因此本文建議在 PC 端進行閱讀。

Vue 是數據驅動的視圖框架,那麼組件間的數據通訊是必然的事情,那麼組件間如何進行數據傳遞呢?html

首先組件間通訊有父子組件、兄弟組件、堂兄弟組件、叔侄組件等,分類太多可能很差理解,咱們暫且分爲:vue

  • 父子組件通訊
  • 子父組件通訊
  • 非父子組件通訊react

    • 兄弟組件通訊
    • 非兄弟組件通訊(不是直屬關係,如堂兄組件、叔侄組件等)

後續的組件間通訊方式的例子就會根據這些分類進行說明。git

Vue 自己提供哪幾種通訊方式?

首先 Vue 靈感源於 angular,支持雙向綁定,Vue 本質仍是單向數據流。跟 React 同樣,組件間最基本的數據流是經過 prop 向子組件傳遞數據。github

props 數據流多層示例圖

這裏列舉一下 Vue 自己支持的通訊方式:vuex

  • prop
  • $emit

    這個其實相似 React 的 props 回調。redux

  • provide / inject

    若是你熟悉 React,這與 React 的 context 特性很類似。api

那麼有人說 $attrs$listener 呢?這些嚴格意義上不能概括爲數據流的通訊方式,這些只是輔助屬性,本人也不建議過多的使用這些 $ 屬性,除了一些有必要的場景。框架

prop

prop 是 Vue 三大核心概念之一,prop 在組件中無處不在。prop 只能夠從上一級組件傳遞到下一級組件(父子組件),即所謂的單向數據流。並且 prop 只讀,不可被修改,全部修改都會失效並警告。ide

能夠先閱讀官網的 經過 Prop 向子組件傳遞數據 的教程。

父子組件通訊

這裏也編寫了一個簡單的例子 http://jsrun.net/wXyKp/edit

子父組件通訊

不是說是單向數據流嗎,怎麼還可使用 prop 進行子父組件通訊?這樣想是對的,prop 是沒法向上傳遞數據,可是咱們可使用回調啊。數據流的確向上走了,可是這並不違反單向數據流的思想,這個並不會使得數據流混亂,仍是比較清晰。

這個 prop 回調方式,在 React 會常用。可是在 Vue 卻不多使用,由於組件能夠自定義事件,即後面的 $emit 組件間通訊方式(其實就是訂閱發佈模式)。

例子能夠看這個 http://jsrun.net/aXyKp/edit

兄弟組件的通訊

若是你瞭解上面提到的父子組件通訊子父組件通訊,那麼你就很容易理解兄弟組件通訊的方式。

能夠看下這個例子 http://jsrun.net/QyyKp/edit

兄弟組件的通訊就是父子組件通訊子父組件通訊的結合,須要父組件做爲中間組件進行數據傳遞。

那麼這樣豈不是很麻煩?的確是多了一步,因此咱們基本不會使用這種方式進行數據傳遞。

可是單向數據流思想是不存在交叉的數據流,即便 vuex 也沒法避免這一步,可是 vuex 用法上你感受不到這一步。因此請不要隨意引入第三方訂閱發佈的類庫來解決這個問題,兄弟組件不能夠直接通訊的問題,這會形成數據流混亂,這就徹底違反了單向數據流的思想。

能夠看下這個強烈不建議的使用例子 http://jsrun.net/PyyKp/edit,這種使用方式徹底違背了單向數據流的思想,當程序複雜起來,數據流會特別混亂,項目很差維護。

$emit

官網教程能夠看監聽子組件事件

$on$emit 是 Vue 自帶的訂閱發佈模式,能夠自定義事件。在子父組件通訊中可使用這種模式代替 prop 回調模式,相對便捷一點。

每一個組件的 $on$emit 都是獨立的,$emit 只會觸發當前組件的 $on 事件。

對比例子能夠看這個 http://jsrun.net/cXyKp/edit

子父組件通訊能夠看上面提到的例子能夠看這個 http://jsrun.net/aXyKp/edit

provide / inject

首先你須要看官網教程 https://cn.vuejs.org/v2/api/#...prviode / inject 在 vue@2.2.0 才新增的。這個也是做者參考 react context ,新加的用法,若是你熟悉 react,那麼這個很好理解。

在組件嵌套比較深的狀況下,咱們再使用 prop 層層傳遞數據將是個噩夢。 孫輩組件想直接獲取到祖輩的數據,而不用通過父輩組件,該怎麼處理呢?provide / inject 能夠解決這個問題。

可看這個使用例子 http://jsrun.net/nXyKp/edit

從上面的例子運行可知,provide 執行與 beforeCreatecreated 之間,也能夠訪問 datainject 的數據。

其餘的通訊方式

除了 vue 自己支持的通訊方式,還有其餘的嗎?固然有 vuex 就是 vue 官方的數據流管理類庫。

上面提到的 vue 自己支持的通訊方式,涉及到的都是父子或者子父組件的通訊,那麼非父子組件通訊呢?經過 vuex 咱們就能夠很簡單的進行非父子組件的通訊了,使用了 vue 支持各類方式的通訊(包括父子組件、子父組件的通訊)。

結合單向數據流的思想,咱們難道不能夠統一一個地方集中管理數據(咱們簡稱 store),而後每一個組件能夠直接和 store 通訊嗎?答案固然能夠,這就是咱們 vuex 所作的事情,這個跟 react 的 redux、mobx 等類庫的思想是一致的。

props 的通訊方式是這樣的,component -> component

而 vuex 的通訊方式是這樣的,component(傳遞數據) -> store -> (數據變化更新組件)component,能夠簡單理解爲 component -> store -> component。咱們在中間搭建了數據管理層,那麼這樣咱們就能夠更好的管理數據了,並且數據流符合單向數據流的思想,數據都是從 store 流向 componentcomponent 能夠是任何嵌套層次的組件。

理論上咱們也能夠在 vue 上使用 redux,可是沒人會這樣作,不合適,vuex 纔是量身定製的。

參考文章


學習和總結文章同步發佈於 https://github.com/xianshanna...,有興趣能夠關注一下,一塊兒學習和進步。
相關文章
相關標籤/搜索