动态

详情 返回 返回

composition events於v-model中的使用 - 动态 详情

前言:我們都知道vue中v-model指令可以實現雙向數據綁定,但他本質是一個語法糖,比如組件上的v-model默認會利用名為value的 prop 和名為input的事件。在自定義實現的過程中,發現在使用輸入法時,輸入拼音選擇候選詞同樣會觸發原生input標籤input事件,從而更新value。但element-ui的input組件便不會如此,其實就是用到了composition events

compositionend事件 當文本段落的組成完成或取消時, compositionend 事件將被觸發 (具有特殊字符的觸發, 需要一系列鍵和其他輸入, 如語音識別或移動中的字詞建議)。

compositionstart事件 觸發於一段文字的輸入之前(類似於keydown事件,但是該事件僅在若干可見字符的輸入之前,而這些可見字符的輸入可能需要一連串的鍵盤操作、語音識別或者點擊輸入法的備選詞)。

compositionupdate 事件觸發於字符被輸入到一段文字的時候(這些可見字符的輸入可能需要一連串的鍵盤操作、語音識別或者點擊輸入法的備選詞)
(內容來自MDN)

<input
:tabindex="tabindex"
v-if="type !== 'textarea'"
class="el-input__inner"
v-bind="$attrs"
:type="showPassword ? (passwordVisible ? 'text': 'password') : type"
:disabled="inputDisabled"
:readonly="readonly"
:autocomplete="autoComplete || autocomplete"
ref="input"

@compositionstart="handleCompositionStart"
@compositionupdate="handleCompositionUpdate"
@compositionend="handleCompositionEnd"
@input="handleInput"

@focus="handleFocus"
@blur="handleBlur"
@change="handleChange"
:aria-label="label"
\>


// 方法
handleCompositionStart() {
    this.isComposing = true;
},
handleCompositionUpdate(event) {
    const text = event.target.value;
    const lastCharacter = text[text.length - 1] || '';
    // 此處通過正則對最後一個字符是否韓文作一個判斷,有懂韓文的請指教一下~
    this.isComposing = !isKorean(lastCharacter);
},

handleCompositionEnd(event) {
    if (this.isComposing) {
        this.isComposing = false;
        this.handleInput(event);
    }
},
handleInput(event) {
    // should not emit input during composition
    if (this.isComposing) return;
    // hack for https://github.com/ElemeFE/element/issues/8548
    // should remove the following line when we don't support IE
    if (event.target.value === this.nativeInputValue) return;
    this.$emit('input', event.target.value);
    // ensure native input value is controlled
    // see: https://github.com/ElemeFE/element/issues/12850
    this.$nextTick(this.setNativeInputValue);
},
handleChange(event) {
    this.$emit('change', event.target.value);
},

可以看到,原生的input綁定了許多事件,其中input事件中,先判斷isComposing的布爾值,看是否觸發了composition events的一系列方法,然後才決定是否執行下段代碼this.$emit('input', event.target.value)

@compositionstart="handleCompositionStart"
@compositionupdate="handleCompositionUpdate"
@compositionend="handleCompositionEnd"
@input="handleInput"`

總結:此事件本身較為簡單,下分只有三個狀態的事件,但是在雙向數據綁定的實現中,又是比較重要的一環,避免在輸入法選詞時連續觸發。看源碼一時爽;一直看源碼一直爽

Add a new 评论

Some HTML is okay.