$emit:向父級傳值
單純從emit角度而言沒啥好說的
組件內(nèi)部$emit('someEvent')
使用組件時:<SomeComponent @someEvent="functionToHandleSomeEvnent">
,注意這里不傳參,someEvent需保持一致
son組件
<template>
<div class="son">
<h1>這是son組件</h1>
<span>來自father的值(fatherToSon1):{{fatherToSon1}}
<button @click="changeFatherToSon1">使用emit</button>
</span>
</div>
</template>
<script>
export default {
name: "Son",
data(){
return {
sonData:1
}
},
props: {
fatherToSon1: Number,
},
methods: {
changeFatherToSon1() {
this.$emit('changeFatherToSon1',2)
}
}
}
</script>
father組件
在使用son組件的地方注冊一個和son組件中emit第一個參數(shù)一樣名字的函數(shù)赖草,簡單來說野哭,就是son組件emit時的第一個參數(shù)要和使用son組件時@后面寫的保持一致夕膀。(@可以理解為給某一個類型的事件綁定一個處理函數(shù)@事件類型=處理該事件的函數(shù)
而柑,像@click
是vue幫我們定義好的吓蘑,而@changeFatherToSon1
是我們自己定義的)
<template>
<div class="father">
<h1>這是father組件</h1>
<p>來自ancestors的值:{{provideFromAncestors}}</p>
<button @click="showRef">$ref訪問子組件</button>
<Son ref="son":fatherToSon1="fatherToSon1" @changeFatherToSon1="changeFatherToSon1"/>
<Son/>
<br>
</div>
</template>
<script>
import Son from './Son'
export default {
name: "Father",
components: {
Son
},
data() {
return {
fatherToSon1: 1,
}
},
methods: {
changeFatherToSon1(value) {
this.fatherToSon1 = value
},
}
}
</script>
$emit相關(guān)變種
1锡垄、$emit('update:value',someValue)
son組件
<template>
<div class="son">
<h1>這是son組件</h1>
<span>
來自father的值(fatherToSon2):{{fatherToSon2}}
<button @click="changeFatherToSon2">使用update:value+@update:value</button>
</span>
</div>
</template>
<script>
export default {
name: "Son",
data(){
return {
sonData:1
}
},
props: {
fatherToSon2: Number
},
methods: {
changeFatherToSon2() {
this.$emit('update:value1',20)
},
}
}
</script>
father組件
<template>
<div class="father">
<h1>這是father組件</h1>
<Son ref="son" :fatherToSon2="fatherToSon2" @update:value1="value=>{this.fatherToSon2=value}"
/>
<Son/>
<br>
</div>
</template>
<script>
import Son from './Son'
export default {
name: "Father",
components: {
Son
},
data() {
return {
fatherToSon2: 10,
}
},
}
</script>
這里value=>{this.fatherToSon2=value}
也可以單獨抽出一個函數(shù)要糊。
父組件還有一種語法糖的寫法
<template>
<div class="father">
<h1>這是father組件</h1>
<Son ref="son" :fatherToSon2="fatherToSon2" :value2.sync="fatherToSon2"
/>
<Son/>
<br>
</div>
</template>
<script>
import Son from './Son'
export default {
name: "Father",
components: {
Son
},
data() {
return {
fatherToSon2: 10,
}
},
}
</script>
@update:value1="value=>{this.fatherToSon2=value}"
改為:value2.sync="fatherToSon2"
即可
2盼砍、$emit('input')
注意闻坚,input事件是vue幫我們定義好的沽翔,我們通過emit來觸發(fā),以達到通信的目的,其實和正常的$emit發(fā)射自定義事件是差不多的
son組件
<template>
<div class="son">
<h1>這是son組件</h1>
<span>
來自father的值(fatherToSon5):{{fatherToSon5}}
<button @click="changeFatherToSon5">emit('input')+@input</button>
</span>
</div>
</template>
<script>
export default {
name: "Son",
data(){
return {
sonData:1
}
},
props: {
fatherToSon5: Number,
},
methods: {
changeFatherToSon5(){
this.$emit('input',20000)
},
}
}
</script>
<style scoped>
.son {
background-color: darkgray;
color: white;
}
</style>
Father組件
<template>
<div class="father">
<h1>這是father組件</h1>
<Son ref="son"
:fatherToSon5="fatherToSon5" @input="value=>{this.fatherToSon5=value}"
/>
<Son/>
<br>
</div>
</template>
<script>
import Son from './Son'
export default {
name: "Father",
components: {
Son
},
data() {
return {
fatherToSon5: 10000
}
},
}
</script>
這里其實也有個語法糖叫v-model窿凤,v-model其實可以理解為:value="somevalue" @input="value=>this.somevalue=value"
的簡寫形式,當我們把這個v-model掛到組件上時仅偎,就可以形成一種新的組件通信方法。
其中子組件不需要改動雳殊,父組件修改
<template>
<div class="father">
<h1>這是father組件</h1>
<Son ref="son"
v-model="fatherToSon5"
/>
<Son/>
<br>
</div>
</template>
<script>
import Son from './Son'
export default {
name: "Father",
components: {
Son
},
data() {
return {
fatherToSon5: 10000
}
},
}
</script>
emit相關(guān)的到這里就結(jié)束了
$root和$parent
這里和$children和$refs類似橘沥,$parent取當前組件實例的父組件實例,而$root取到根節(jié)點的組件相种,往往是app組件
$parent:向上派發(fā)事件
此處需要結(jié)合$emit一起食用
emit往往用于子組件通知父組件更新某個父組件的值威恼,但是當組件層級達到三層即(son-father-grandpa)時,需要在son中使用$parent.$emit進行事件發(fā)射如果層級更深顯然不可能無限$parent寝并,于是我們需要讓子組件調(diào)用$eventDispatch箫措,讓這個子組件向上的每一級父組件都進行$emit,一旦調(diào)用emit的組件的父組件監(jiān)聽了對應(yīng)的事件衬潦,那么就會執(zhí)行斤蔓。
Vue.prototype.$eventDispatch = function (event, value) {
let parent = this.$parent
while (parent) {
parent.$emit(event, value)
parent = parent.$parent
}
}
舉例:我們在ancestors上監(jiān)聽了emitToUpper
事件
<template>
<div class="ancestors">
<h1>這是祖先組件</h1>
<grand-pa @emitToUpper="dispatchToAncester"/>
</div>
</template>
<script>
import GrandPa from './GrandPa'
export default {
name: "Ancestors",
components:{
GrandPa
},
methods:{
dispatchToAncester(value){
console.log(`ancestors監(jiān)聽到了一個事件,值為${value}`);
},
}
}
</script>
<style scoped>
</style>
同樣的,在app組件也可以進行監(jiān)聽emitToUpper
事件
<template>
<Ancestors @emitToUpper="dispatchToApp"/>
</template>
<script>
import Ancestors from '@/components/Ancestors'
export default {
name: 'App',
components: {
Ancestors
},
methods:{
dispatchToApp(value){
console.log(`app監(jiān)聽到了一個事件,值為${value}`);
}
}
}
</script>
<style>
</style>
只要監(jiān)聽了@emitToUpper事件的組件都會觸發(fā)對應(yīng)的函數(shù)
<template>
<div class="son">
<h1>這是son組件</h1>
<button @click="emitToUpper">使用$eventDispatch發(fā)射事件</button>
</div>
</template>
<script>
export default {
name: "Son",
methods: {
emitToUpper(){
this.$eventDispatch('emitToUpper','aaaa')
},
}
}
</script>
<style scoped>
</style>