vue組件通訊方式不少同窗會說我知道,這個簡單,props傳值,$emit回傳,再不行就vuex。但實際上vue組件通訊遠遠不止這些,並非層級一多就要用vuex,一個項目就要隔多級傳幾個靜態參數,你說我用vuex,我想這就是殺雞用了宰牛刀,今天就來講一下具體有多少種方式,而且如何應用。vue
組件通訊經常使用方式vuex
一、props/$emit。
二、event。
三、vuex。
自定義事件
1.邊界狀況api
四、 $parent。
五、 $root。
六、 $children。
七、 $refs。
八、 provide/inject。
2.非prop特性數組
九、 $attrs。
十、 $listeners。
1.props/$emit
props傳值很是簡單,這個是最最經常使用的,我簡單寫下例子。app
父組件給子組件傳值dom
// parent 組件 <Parent msg="Welcome to vue props"/> // child裏面經過props獲取msg props: { msg: String }
子組件傳值給父組件,使用$emitide
// child裏面調用$emit, 第一個參數是方法名,後面都是參數 this.$emit('add', good) // parent,$emit會觸發父組件add方法 <Parent @add="parentAdd($event)" />
2.event事件總線
前面說到的props和/$emit父子組件通訊,他們存在引入與被引入的關係,若是不存在這種關係咱們該怎麼辦呢?
這時咱們經常會用到事件總線或者vuex的方式。學習
首先在main.js文件中經過vue原型屬性初始化EventBus,
這種方式初始化的是一個全局事件總線。ui
import Vue from 'vue' import App from './App.vue' // 事件總線 Vue.prototype.$bus = new Vue() new Vue({ render: h => h(App), }).$mount('#app')
在組件1中發送信息this
// 利用事件總線發送事件 this.$bus.$emit('event-from-component1', 'some msg from component1')
在組件2中監聽接受信息
this.$bus.$on('event-from-component1', msg => { console.log('component2:', msg); });
這時只要在組件1中觸發$bus.$emit的方法,組件2中$bus.$on方法就會調用,控制檯就會輸出:
3.vuex
建立惟一的全局數據管理者store,經過它管理數據並通知組件狀態變動。
vuex的強大這裏就不贅述了,vuex內容比較多也不是本文的主題,這裏就不細講了,不熟悉的同窗先去看下官網:https://vuex.vuejs.org/zh/guide
4.$parent
兄弟組件直接能夠經過共同的祖先搭橋聯通,$parent和$root均可以作到。
// brother1中發出方法 this.$parent.$emit('event-from-brother1', 'some msg from brother1')` // brother2中接收方法 this.$parent.$on('event-from-brother1', msg => { console.log('brother2:', msg); });
這時觸發brother1中的方法,控制檯就會顯示:
這是兄弟組件通訊的方法,咱們也能夠經過$parent從子組件調用父組件的方法。
// parent裏面methods定義了一個方法 methods: { fatherMethod() { console.log('我是你爹'); } } // children子組件裏面調用父組件方法 this.$parent.fatherMethod()
當$parent.fatherMethod()方法在子組件被調用控制檯便會打出:我是你爹
5.$root
$root和上面parent相似,這裏就不贅述,具體請移步官網。
6.$children
父組件能夠經過$children訪問子組件實現父子通訊,可是父組件可能含有多個子組件,因此要區分開
this.$children[index].xx = 'xxx'
可是有一點須要注意$children實際上不能保證子元素的順序,也不是響應式的。
由於$children
是根據你頁面加載組件的順序去肯定子組件在 $children
數組中的順序。
若是A組件在B組件先加載,那麼A組件的下標就是0,B組件的下標就是1。
若是有動態組件很容易出錯,因此咱們並不建議使用。
然而咱們經常使用的$refs
就能夠解決這個問題。
7.$refs
回去節點引用,也就是獲取dom
// dom中引入 <div ref="tx" /> // 獲取上面div的dom從而操做 this.$refs.tx
在父組件中經過ref調用子組件的方法,這裏就不會有$children的順序問題了,由於ref是一一對應的。
// 父組件 <Child2 ref="child2" msg="some message"></Child2> // 子組件 methods: { sendToChild1() { console.log('我是父組件使用ref調用的方法') } }, // 在父組件中調用子組件方法sendToChild1 `this.$refs.child2.sendToChild1()`
8.provide/inject
可以很好的跨層級通訊。官網也作比較詳細的說明:https://cn.vuejs.org/v2/api/#...。
這個方法其實也挺好用的,可是不少同窗並無用過,可能都不是很清楚。
下面咱們來具體說一下:
// 祖輩組件中提供了一個變量,這時咱們使用provide方法注入 provide() { return { father: 'father' } }, // 這時咱們須要在某個後代元素中獲取這個father變量 // 注入以後咱們就能夠在該後代組件中使用變量father了 inject: ['father'] // inject另一種寫法 // 這時咱們須要對變量重命名,同時能夠設置默認值 inject: { bar1: { from: 'father', default: 'barrrrrrrr' } },
咱們也能夠把注入值放入咱們該後代元素的data中去使用,provide/inject基本用法就是這樣的。
9.$attrs
$attrs包含了父做用域中不做爲 prop 被識別 (且獲取) 的特性綁定 ( class 和 style 除外)。
當一個組件沒有 聲明任何 prop 時,這裏會包含全部父做用域的綁定 ( class 和 style 除外),而且能夠經過 v- bind="$attrs" 傳入內部組件——在建立高級別的組件時很是有用。
// 爺爺組件中給父親組件注入信息 <Parent msg="msg" /> // 父親組件,咱們須要在父親組件中綁定$attr以便於孫子組件獲取信息 <Children v-bind="$attrs" /> // 孫子組件:在props中沒有聲明msg,這時子組件依然可以收到信息 <div> {{$attrs.msg}}</div>
這時孫子組件就能夠獲取msg的信息了,這裏其實都是跨層級通訊的。
10.$listeners
若是咱們須要從孫子組件調用爺爺組件的方法,實現跨層級通訊的話,可使用到$listeners。
// 爺爺組件 <Parent msg="msg" @foo="onFoo"/> // 爺爺組件methods設置方法 onFoo() { console.log('msg from Children'); } // 父親組件,綁定$listeners <Children v-bind="$attrs" v-on="$listeners" /> // 孫子組件:調用foo方法 this.$emit('foo')
以上內容只是本人的學習總結,緊供參考。