總結:Vue元件間的通信
一、父子元件
1、父元件傳值屬性傳參,子元件
props
接收
例:
父元件:
<div>
<child val="val"></child>
</div>
子元件:
<script>
export default {
props: {
val: {
type: String,
default: ''
}
}
}
</script>
2、
$attrs
接收父元件傳值,但沒有在子元件props聲明
例:
父元件:
<div>
<child val="val"></child>
</div>
子元件:
<div>
<div v-bind="$attrs" :val="$attrs.val"></div>
</div>
注意
:
v-bind="$attrs"
此種方式
$attrs
會以鍵值對的形式預設展開在目前節點,但是目前執行個體的根節點會繼承
$attrs
展開的屬性
解決:
export default {
inheritAttrs: false
}
3、
$refs
父元件擷取子元件執行個體進而修改子元件的資料
例:
父元件:
<div>
<child ref="child"></child>
</div>
export default {
mounted () {
this.$refs.child.val = '111111111111'
}
}
子元件:
export default {
data() {
return {
val: '1'
}
}
}
4、
$children
父元件擷取子元件執行個體進而修改子元件的資料
父元件:
<div>
<child></child>
</div>
export default {
mounted () {
this.$children[0].val = '111111111111'
}
}
子元件:
export default {
data() {
return {
val: '1'
}
}
}
注意
:此種方式不推薦使用,因為父元件内可能會有很多子元件,并且子元件有可能是為異步元件,是以父元件内各個子元件執行個體的順序即
index
下标并不一定是固定的,是以有可能會導緻擷取改變失敗。
5、
$emit
子元件派發事件,父元件内的子元件監聽事件(事件由派發者監聽)
子元件:
<div>
<button @click="clickBtn">點選派發事件</button>
</div>
export default {
methods () {
clickBtn () {
this.$emit('myClick', '子元件内部點選觸發')
}
}
}
父元件:
<div>
<child @myClick="myClick"></child>
</div>
export default {
methods () {
myClick (val) {
console.log(val) // 子元件内部點選觸發
}
}
}
注意
: 常用此種方式進行子元件向父元件的通信
二、兄弟元件之間的通信
注意:兄弟元件間的通信通常會使用第三方傳遞,即兄弟元件共同的父輩或者祖輩來傳遞資料
注意:兄弟元件間的通信通常會使用第三方傳遞,即兄弟元件共同的父輩或者祖輩來傳遞資料
例
父輩元件:$parent || $root
<div>
<child1></child1>
<child2></child2>
</div>
子元件1:子元件1點選觸發通訊給子元件2
<div>
<div @click="say2"></div>
</div>
export default {
methods () {
say2 () {
this.$parent.$emit('receice1')
}
}
}
子元件2:子元件2内部監聽子元件1觸發的通信
export default {
mounted () {
this.$parent.$on('receive1', () => {
console.log('我接收到了來自兄弟的通信')
})
}
}
三、祖先和後代間的通信(跨很多元件) provide
、 inject
provide
inject
正常很少使用這種方式,元件開發的時候偶爾會用到
正常很少使用這種方式,元件開發的時候偶爾會用到
例
祖先節點:
export default {
provide () {
return {
val: 111
}
}
}
後代節點:
export default {
inject: [
'val'
]
}
注意:單向傳遞資料(由祖先-》後代)
四、任意兩個元件間的通信 vuex
、事件總線 bus
vuex
bus
1、
vuex
采用最多的一種方式,不做示例
2、事件總線
bus
:
抽離出
bus
bus.js
import Vue from 'vue'
const Bus = new Vue()
export default Bus
使用
bus
import Bus from './utils/bus'
Bus.$emit('busHandle')
Bus.$on('busHandle', () => {})
注意
:注冊的總線事件要在元件銷毀時解除安裝,否則會多次挂載,造成觸發一次但多個響應的情況
export default {
beforeDestroy () {
this.bus.$off('busHandle')
}
}
模拟
BUS
的實作
// bus.js
class Bus {
constructor: {
this.classback = {} // 用來存儲所有的事件
}
$on (name, fn) { // name:事件名形參名,fn為事件回調函數
this.callback[name] = this.callback[name] || [] // 當name第一次被監聽,則建立一個名為name的數組,用來存儲所有的該name的回調函數
this.callback[name].push(fn)
}
$emit (name, args) { // name、args觸發回調函數傳遞的參數
if (this.callback[name]) {
this.callback[name].forEach((cb) => {
cb(args) // 觸發目前name身上綁定的所有的回調函數
})
}
}
}
export default Bus
使用:引入
bus
(
bus.$on
、
bus.$emit
)