做(zuò)自(zì)由與創造的先行(xíng)者

組件事件

Vue.js中文手冊

此章(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)發
下(xià)一(yī)篇:組件 v-model
上(shàng)一(yī)篇:Props