最近在阅读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