例子是在 jsrun.net 平臺編寫,不支持移動端平臺,因此本文建議在 PC 端進行閱讀。
Vue 是數據驅動的視圖框架,那麼組件間的數據通訊是必然的事情,那麼組件間如何進行數據傳遞呢?html
首先組件間通訊有父子組件、兄弟組件、堂兄弟組件、叔侄組件等,分類太多可能很差理解,咱們暫且分爲:vue
非父子組件通訊react
後續的組件間通訊方式的例子就會根據這些分類進行說明。git
首先 Vue 靈感源於 angular,支持雙向綁定,Vue 本質仍是單向數據流。跟 React 同樣,組件間最基本的數據流是經過 prop 向子組件傳遞數據。github
這裏列舉一下 Vue 自己支持的通訊方式:vuex
這個其實相似 React 的 props 回調。redux
若是你熟悉 React,這與 React 的 context 特性很類似。api
那麼有人說 $attrs
、$listener
呢?這些嚴格意義上不能概括爲數據流的通訊方式,這些只是輔助屬性,本人也不建議過多的使用這些 $
屬性,除了一些有必要的場景。框架
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,這種使用方式徹底違背了單向數據流的思想,當程序複雜起來,數據流會特別混亂,項目很差維護。
官網教程能夠看監聽子組件事件。
$on
和 $emit
是 Vue 自帶的訂閱發佈模式,能夠自定義事件。在子父組件通訊
中可使用這種模式代替 prop 回調模式,相對便捷一點。
每一個組件的 $on
和 $emit
都是獨立的,$emit
只會觸發當前組件的 $on
事件。
對比例子能夠看這個 http://jsrun.net/cXyKp/edit。
子父組件通訊能夠看上面提到的例子能夠看這個 http://jsrun.net/aXyKp/edit。
首先你須要看官網教程 https://cn.vuejs.org/v2/api/#...。 prviode / inject
在 vue@2.2.0 才新增的。這個也是做者參考 react context ,新加的用法,若是你熟悉 react,那麼這個很好理解。
在組件嵌套比較深的狀況下,咱們再使用 prop 層層傳遞數據將是個噩夢。 孫輩組件想直接獲取到祖輩的數據,而不用通過父輩組件,該怎麼處理呢?provide / inject
能夠解決這個問題。
可看這個使用例子 http://jsrun.net/nXyKp/edit。
從上面的例子運行可知,provide
執行與 beforeCreate
和 created
之間,也能夠訪問 data
和 inject
的數據。
除了 vue 自己支持的通訊方式,還有其餘的嗎?固然有 vuex 就是 vue 官方的數據流管理類庫。
上面提到的 vue 自己支持的通訊方式,涉及到的都是父子或者子父組件的通訊,那麼非父子組件通訊呢?經過 vuex 咱們就能夠很簡單的進行非父子組件的通訊了,使用了 vue 支持各類方式的通訊(包括父子組件、子父組件的通訊)。
結合單向數據流的思想,咱們難道不能夠統一一個地方集中管理數據(咱們簡稱 store),而後每一個組件能夠直接和 store
通訊嗎?答案固然能夠,這就是咱們 vuex 所作的事情,這個跟 react 的 redux、mobx 等類庫的思想是一致的。
props 的通訊方式是這樣的,component
-> component
。
而 vuex 的通訊方式是這樣的,component(傳遞數據)
-> store
-> (數據變化更新組件)component
,能夠簡單理解爲 component
-> store
-> component
。咱們在中間搭建了數據管理層,那麼這樣咱們就能夠更好的管理數據了,並且數據流符合單向數據流的思想,數據都是從 store
流向 component
,component
能夠是任何嵌套層次的組件。
理論上咱們也能夠在 vue 上使用 redux,可是沒人會這樣作,不合適,vuex 纔是量身定製的。
學習和總結文章同步發佈於 https://github.com/xianshanna...,有興趣能夠關注一下,一塊兒學習和進步。