最近在閱讀Element-UI的input組件源碼時,發現其使用了composition事件:javascript
<input :tabindex="tabindex" v-if="type !== 'textarea'" class="el-input__inner" v-bind="$attrs" :type="type" :disabled="inputDisabled" :readonly="readonly" :autocomplete="autoComplete || autocomplete" :value="currentValue" ref="input" @compositionstart="handleComposition" // 注意這裏! @compositionupdate="handleComposition" // 注意這裏! @compositionend="handleComposition" // 注意這裏! @input="handleInput" @focus="handleFocus" @blur="handleBlur" @change="handleChange" :aria-label="label" >
複製代碼
印象裏紅皮書好像有提到過,但已經記不清有什麼做用了,趁此機會學習下。html
composition event,即複合事件,用於處理IME的輸入序列。 IME(Input Method Editor,輸入法編輯器)可讓用戶輸入在物理鍵盤上找不到的字符。 其實就是咱們用中文輸入法時,出現的顯示中文的框: java
composition event包括三個事件:編輯器
那Element-UI爲何要使用composition event呢? 這其實跟composition event的做用有關,咱們來看下compotion event與input event的觸發順序: post
二者分別會觸發input和compositionupdate事件。這樣問題就出現了,用過Element-UI或者相似UI庫的同窗都知道,input組件多數狀況下都是配合着form組件使用的,既然是表單,那也離不開表單驗證了。那麼問題就在於,若是是經過input事件來觸發驗證的,輸入的是字符,那倒沒什麼問題。可要是輸入的是中文(或者其它須要組合拼出來的語言),好比,要輸入'我',在拼音還沒轉換以前,網頁輸入框中的內容時'wo',也會觸發驗證,這並非咱們想要的!學習
所以,咱們可使用複合事件,經過一個變量來判斷是不是在composition event中,是,就不去觸發input事件。 固然,Element-UI也是這麼作:this
handleComposition(event) {
if (event.type === 'compositionend') {
this.isOnComposition = false;
this.currentValue = this.valueBeforeComposition;
this.valueBeforeComposition = null;
this.handleInput(event);
} else {
const text = event.target.value;
const lastCharacter = text[text.length - 1] || '';
this.isOnComposition = !isKorean(lastCharacter);
if (this.isOnComposition && event.type === 'compositionstart') {
this.valueBeforeComposition = text;
}
}
}
複製代碼
該方法是composition event的統一處理方法,this.isOnComposition用來判是否開啓了輸入法,在compositionend事件觸發時,將this.isOnCompostion = false; 代表輸入法已關閉,再去執行this.handleInput,即input事件的處理方法。spa
handleInput(event) {
const value = event.target.value;
this.setCurrentValue(value);
if (this.isOnComposition) return;
this.$emit('input', value);
}
複製代碼
在handleInput方法中,能夠看到,若this.isOnComposition爲true,是不會執行this.$('input', value);的,即不會向父組件派發input事件,若是父組件是form組件,也就不會去觸發表單驗證了。code