在vue開(kāi)發(fā)過(guò)程中,我們經(jīng)常會(huì)使用組件傳值來(lái)實(shí)現(xiàn)頁(yè)面之間的數(shù)據(jù)傳遞。其中,一種常見(jiàn)的方式是使用子組件向父級(jí)組件傳遞數(shù)據(jù),這時(shí)就需要使用到vue中的$emit方法。但是,有時(shí)候我們會(huì)發(fā)現(xiàn)$emit方法并沒(méi)有起到作用,本篇文章將分析并解決這一問(wèn)題。
下面我們來(lái)看一個(gè)例子:
<template>
<div>
<child-component @send-something="getValue"></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
methods: {
getValue(val) {
console.log(val);
}
}
}
</script>
在其中,我們引入了一個(gè)子組件ChildComponent,當(dāng)ChildComponent中觸發(fā)了send-something事件時(shí),把值傳到父級(jí)組件中,由父級(jí)組件調(diào)用getValue方法對(duì)這個(gè)值進(jìn)行處理。
// 子組件ChildComponent
<template>
<div @click="send">click me</div>
</template>
<script>
export default {
methods: {
send() {
this.$emit('send-something', 'hello');
}
}
}
</script>
在子組件中,我們?cè)邳c(diǎn)擊事件中使用$emit('send-something', 'hello')觸發(fā)了send-something事件,這里我們需要注意,vue中需要將事件名稱改為kebab-case的格式,即使用'-'連接。
然而,當(dāng)我們運(yùn)行這段代碼后卻發(fā)現(xiàn),父級(jí)組件并沒(méi)有成功的接收到子組件傳遞的數(shù)據(jù)。這時(shí)候我們可以使用vue-devtools來(lái)輔助調(diào)試,可以看到點(diǎn)擊ChildComponent組件后觸發(fā)的send-something事件并沒(méi)有傳遞出去,也就是$emit并沒(méi)有起到作用。
經(jīng)過(guò)調(diào)試我們發(fā)現(xiàn),這是因?yàn)樵谧咏M件中使用this.$emit傳遞事件時(shí),只能傳遞固定的字符串形式的事件名稱,而無(wú)法動(dòng)態(tài)的傳遞變量。因此,正確的實(shí)現(xiàn)方式如下:
<template>
<div @click="send">click me</div>
</template>
<script>
export default {
props: {
eventName: {
type: String,
default: 'send-something'
}
},
methods: {
send() {
this.$emit(this.eventName, 'hello');
}
}
}
</script>
通過(guò)在子組件中添加一個(gè)props屬性eventName,限定eventName的類型為String,并默認(rèn)為send-something,再在$emit方法中使用this.eventName動(dòng)態(tài)的傳遞事件名稱,從而解決了$emit無(wú)效的問(wèn)題。