天天看點

總結:VUE元件間的通信

總結: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

正常很少使用這種方式,元件開發的時候偶爾會用到

祖先節點:

export default {
	provide () {
		return {
			val: 111
		}
	}
}
           

後代節點:

export default {
	inject: [
		'val'
	]
}
           

注意:單向傳遞資料(由祖先-》後代)

四、任意兩個元件間的通信

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