vue中的組件通訊是必不可少的使用場景,回顧了平時使用vue中碰到的一些業務場景和對應採用的組件通訊方式,簡單地作了一個歸類總結,大體有如下一些通訊方式:vue
最經常使用的父子組件通訊方式,父組件經過props向子組件傳值,子組件經過$emit事件向父組件觸發事件並傳值vuex
//父組件 <parent :name="xxx" @updateFromChild="xxx"></parent> //子組件 props: { name: { type: String, default: '' } } methods: { xxx () { this.$emit('updateFromChild', xx) } }
子組件中獲取除了在props中定義以外的父組件中傳遞的屬性值(class 和 style 除外)數組
//父組件 <parent name="小明" age=5 sex="男" home="杭州" class="parent"></parent> //子組件 <script> props: { name: { type: String, default: '' } } mounted () { console.log(this.$attrs) // {age:5, sex:"男", home:"杭州"} } </script>
當孫組件中須要用到爺組件中的大量屬性,可是父組件卻不須要用到不少,只是做爲一箇中轉的傳遞,巧用$attrs能夠節省在父組件中寫的props值。dom
//父組件 <parent name="小明" age=5 sex="男" home="杭州" class="parent"></parent> //子組件 <template> <grand-son :passAttr="$attrs"></grand-son> </template> props: { name: { type: String, default: '' } }
包含了父做用域中的 (不含 .native 修飾器的) v-on 事件監聽器。ide
//父組件 <parent @change="onChange" @hide="OnHide"></parent> //子組件 <script> mounted () { console.log(this.$listener) // {change:f, hide:f} } </script>
子組件中調用父組件的方法函數
是一個對象或返回一個對象的函數。該對象包含可注入其子孫的屬性ui
是一個數組或者對象,包含祖先組件中注入的屬性this
//父組件: <script> provide: { name: '小明', sayName () { console.log('我是' + this.name) } } mounted() { this.name = '小花' } </script> //子組件 <script> inject:['name', 'sayName'], mounted () { console.log(this.name); //小明 this.sayName() //我是小明 } </script>
能夠看到在子組件中的 mounted 中打印出了 inject 中傳遞進來的 name 屬性,併成功執行了 sayName 方法。並且 name 屬性值仍是'小明',並無變成'小花',並非響應式的。code
已建立的實例的父實例和子實例中,子實例能夠用 this.\$parent 訪問父實例,子實例被推入父實例的 \$children 數組中,父實例能夠用 this.$children 訪問子實例。對象
//父組件 mounted(){ console.log(this.$children) //能夠操做子組件的data,或者調用其methods中的方法 } //子組件 mounted(){ console.log(this.$parent) //能夠拿到父組件中的屬性和方法 }
一個對象,持有註冊過 ref attribute 的全部 DOM 元素和組件實例。經過this.$refs.xxx 能夠拿到 xxx 子組件中的data和methods。
//父組件 <child ref="child"></child> mounted(){ this.$refs.child.sayHello() // hello } //子組件 methods: { sayHello () { console.log('hello') } }
經過 this.$refs.xxx 進行對子組件的屬性操做並非響應式的,所以避免在computed中進行使用。這是一個很好的應急手段,經常使用於如下兩種使用場景
很少說,強大的複雜單頁面全局數據通訊管理中心,供頁面中的每一個組件進行全局數據的操做,並響應式到各個組件中。若是不知道自行搜索。這裏就簡單說兩個注意點
對於非父子組件來講,能夠採用一箇中間介質來做爲一箇中央事件總線,完成事件的觸發和監聽,並進行傳值。
第一步:建立事件總線:創建一個eventBus.js文件
//僅僅是爲了建立一個vue實例 import Vue from 'vue' export default new Vue()
第二步:在傳值的源頭組件中引進事件總線,進行事件的觸發和傳值
<template> <div class = "source"> <button @click="emitEvent"> </div> </template> <script> import eventBus from './eventBus.js' export default { methods: { emitEvent: funciton () { eventBus.$emit('sendVal',param) } } } </script>
第三步:在傳值的目標組件中引進事件總線,進行事件的監聽和傳值的接收
<template> </template> <script> import eventBus from './eventBus.js' export default { data: function () { return { requireVal: '' } } mounted: function () { var that = this eventBus.$on('sendVal',function(val){ that.requireVal = val }) } } </script>
總結以下:
1.建立一個事件總線,例如demo中的eventBus,用它做爲通訊橋樑
2.在須要傳值的組件中用bus.$emit觸發一個自定義事件,並傳遞參數
3.在須要接收數據的組件中用bus.$on監聽自定義事件,並在回調函數中處理傳遞過來的參數