非父子之間傳值,能夠採用發佈訂閱模式,這種模式在 Vue 中被稱爲總線機制,或者叫作Bus
/ 發佈訂閱模式 / 觀察者模式vue
<div id="root"> <child content="Dell"></child> <child content="Lee"></child> </div> Vue.prototype.bus = new Vue() //掛載 bus 屬性 Vue.component('child', { data(){ return { selfContent: this.content } }, props: { content:String }, template: '<div @click="handleChildClick">{{selfContent}}</div>', methods: { handleChildClick() { this.bus.$emit('change',this.selfContent) // 發佈 } }, mounted(){ this.bus.$on('change',(msg)=>{ //訂閱,這裏會被執行兩次 this.selfContent = msg }) } }) let vm = new Vue({ el: '#root' })
Vue.prototype.bus = new Vue()
這句話的意思是,在 Vue 的prototype
掛載了一個bus
屬性,這個屬性指向 Vue 的實例,只要咱們以後調用 Vue 或者new Vue
時,每一個組件都會有一個bus
屬性,由於之後無論是 Vue 的屬性仍是 Vue 的實例,都是經過 Vue 來建立的,而我在 Vue 的prototype
上掛載了一個bus
的屬性。vuex
組件被掛載以前會執行mounted
鉤子函數,因此能夠在mounted
中對change
事件進行監聽。框架
this.bus.$on()
那邊會被執行兩次,緣由是什麼呢?由於在一個child
組件裏面,觸發事件的時候,外面兩個child
的組件都進行了同一個事件的監聽,因此兩個child
的組件都會執行一遍this.bus.$on()
異步
Vuex
兩個兄弟組件之間公共的父組件,那麼它們就無法經過一個公用的父組件來進行數據的中轉,要實現這兩個頁面組件的數據通訊應該怎麼辦呢?函數
vuex
是 Vue 官方推薦的數據框架,在 Vue 的大型項目開發之中,Vue 只能承擔視圖層的內容,而當咱們涉及到大量數據傳遞的時候,每每都須要一個數據框架進行輔助,Vue 之中這個數據框架就是vuex
this
看上圖vuex
指的是整個圖中虛線部分的內容。spa
那vuex
是什麼呢?當咱們的一個項目之中,好比說多個組件之間進行復雜的數據傳遞很困難的時候,若是能把這些公用的數據,放在一個公共的存儲空間去存儲,而後某一個組件改變了這個公共的數據,其餘的組件就能感知到,不就能夠了嗎。vuex
的設計理念就是這樣的。prototype
回到上圖,右側虛線那塊的圖就是公用數據存儲區域,咱們能夠把這個區域理解成store
倉庫,這個倉庫是由幾部分組成的:設計
State
:它是幹嗎用的呢?咱們全部的公用數據都存放在State
當中,那組件想要用公用的數據,直接去調用State
就能夠了Actions
:有些時候想要改變State
中的數據,可是不能讓組件直接改變State
中的數據,必須走一個流程。這裏有一些異步操做,將這些異步操做放在Actions
,或者一些複雜的同步操做(批量),也能夠放在Actions
中Mutations
:組件想要改變數據先去調用Actions
,經過Actions
去調用Mutations
,Mutations
中放的是一個個同步的修改State
的方法結論:只有經過Mutations
才能改變State
中公用數據的值,這一步也不是絕對的,有時候能夠略過Actions
這一步,讓組件直接調用Mutations
修改State
中的數據。這裏須要注意的是組件調用Actions
是經過Dispatch
方法,而組件直接調用Actions
或者Actions
調用Mutations
是經過Commit
方法。code
其實它就是一個單向數據的改變流程。
具體看下代碼是怎麼實現的:
export default new Vuex.store({ state: { name: '每天' }, actions: { changeName (ctx, name) { //ctx 是上下文 ctx.commit('changeName', name) //經過 commit 調用 mutations 去改變 state,這個 changeName 能夠本身隨便起名字保證和 mutations 中同樣便可 } }, mutations: { changeName (state, name) { state.name = name } } })
組件須要使用就能夠直接這樣使用this.$store.state.name
當其餘地方須要修改name
時,能夠這樣寫
handleNameClick (name) { this.$store.dispatch('changeName', name) //派發一個名字叫 changeName 的 Actions,並把 name 傳過去 }
這邊我在改變state
時沒有任何異步操做,並且這個操做也很是簡單,這個時候組件其實沒有必要去調用Actions
作這個轉發,組件能夠直接去調用mutations
。
handleNameClick (name) { this.$store.commit('changeName', name) //派發一個名字叫 changeName 的 mutation,並把 name 傳遞過去。因此上面的 store 裏能夠把 Actions 給刪除了。 }