此章(zhāng)節假設你已經看(kàn)過了(le)組件基礎。若你還不了(le)解組件是什麽,請(qǐng)先閱讀該章(zhāng)節。
觸發與監聽事件
在組件的模闆表達式中,可(kě)以直接使用 $emit 方法觸發自(zì)定義事件 (例如(rú):在 v-on 的處理函數(shù)中):
template
<!-- MyComponent -->
<button @click="$emit('someEvent')">click me</button>
$emit() 方法在組件實例上(shàng)也同樣以 this.$emit() 的形式可(kě)用:
js
export default {
methods: {
submit() {
this.$emit('someEvent')
}
}
}
父組件可(kě)以通(tōng)過 v-on (縮寫為(wèi) @) 來監聽事件:
template
<MyComponent @some-event="callback" />
同樣,組件的事件監聽器也支持 .once 修飾符:
template
<MyComponent @some-event.once="callback" />
像組件與 prop 一(yī)樣,事件的名字也提供了(le)自(zì)動的格式轉換。注意這(zhè)裏我們觸發了(le)一(yī)個以 camelCase 形式命名的事件,但(dàn)在父組件中可(kě)以使用 kebab-case 形式來監聽。與 prop 大小寫格式一(yī)樣,在模闆中我們也推薦使用 kebab-case 形式來編寫監聽器。
TIP
和(hé)原生 DOM 事件不一(yī)樣,組件觸發的事件沒有冒泡機制。你隻能(néng)監聽直接子組件觸發的事件。平級組件或是跨越多層嵌套的組件間(jiān)通(tōng)信,應使用一(yī)個外(wài)部的事件總線,或是使用一(yī)個全局狀态管理方案。
事件參數(shù)
有時(shí)候我們會需要(yào)在觸發事件時(shí)附帶一(yī)個特定的值。舉例來說,我們想要(yào) <BlogPost> 組件來管理文本會縮放得多大。在這(zhè)個場景下(xià),我們可(kě)以給 $emit 提供一(yī)個額外(wài)的參數(shù):
template
<button @click="$emit('increaseBy', 1)">
Increase by 1
</button>
然後我們在父組件中監聽事件,我們可(kě)以先簡單寫一(yī)個內(nèi)聯的箭頭函數(shù)作(zuò)為(wèi)監聽器,此函數(shù)會接收到事件附帶的參數(shù):
template
<MyButton @increase-by="(n) => count += n" />
或者,也可(kě)以用一(yī)個組件方法來作(zuò)為(wèi)事件處理函數(shù):
template
<MyButton @increase-by="increaseCount" />
該方法也會接收到事件所傳遞的參數(shù):
js
methods: {
increaseCount(n) {
this.count += n
}
}
TIP
所有傳入 $emit() 的額外(wài)參數(shù)都(dōu)會被直接傳向監聽器。舉例來說,$emit('foo', 1, 2, 3) 觸發後,監聽器函數(shù)将會收到這(zhè)三個參數(shù)值。
聲明(míng)觸發的事件
組件可(kě)以顯式地(dì)通(tōng)過 emits 選項來聲明(míng)它要(yào)觸發的事件:
js
export default {
emits: ['inFocus', 'submit']
}
這(zhè)個 emits 選項還支持對象語法,它允許我們對觸發事件的參數(shù)進行(xíng)驗證:
js
export default {
emits: {
submit(payload) {
// 通(tōng)過返回值為(wèi) `true` 還是為(wèi) `false` 來判斷
// 驗證是否通(tōng)過
}
}
}
TypeScript 用戶請(qǐng)參考:如(rú)何為(wèi)組件所抛出的事件标注類型。
盡管事件聲明(míng)是可(kě)選的,我們還是推薦你完整地(dì)聲明(míng)所有要(yào)觸發的事件,以此在代碼中作(zuò)為(wèi)文檔記錄組件的用法。同時(shí),事件聲明(míng)能(néng)讓 Vue 更好地(dì)将事件和(hé)透傳 attribute 作(zuò)出區(qū)分,從(cóng)而避免一(yī)些由第三方代碼觸發的自(zì)定義 DOM 事件所導緻的邊界情況。
TIP
如(rú)果一(yī)個原生事件的名字 (例如(rú) click) 被定義在 emits 選項中,則監聽器隻會監聽組件觸發的 click 事件而不會再響應原生的 click 事件。
事件校驗
和(hé)對 props 添加類型校驗的方式類似,所有觸發的事件也可(kě)以使用對象形式來描述。
要(yào)為(wèi)事件添加校驗,那(nà)麽事件可(kě)以被賦值為(wèi)一(yī)個函數(shù),接受的參數(shù)就是抛出事件時(shí)傳入 this.$emit 的內(nèi)容,返回一(yī)個布爾值來表明(míng)事件是否合法。
js
export default {
emits: {
// 沒有校驗
click: null,
// 校驗 submit 事件
submit: ({ email, password }) => {
if (email && password) {
return true
} else {
console.warn('Invalid submit event payload!')
return false
}
}
},
methods: {
submitForm(email, password) {
this.$emit('submit', { email, password })
}
}
}
網站建設開(kāi)發|APP設計開(kāi)發|小程序建設開(kāi)發