使用input事件监听输入框变化时,如果当前使用的输入法是中文,他也会触发input事件,正常来说,中文没有输入完毕是不用触发事件的。
控制台打印时发现:
那么我们应该怎么去规避这件事呢?
其实input还有几个事件:
- compositionstart:事件在用户开始使用输入法输入时触发。
- onCompositionUpdate:事件在用户正在使用输入法输入时触发
- compositionend: 事件在用户完成使用输入法输入时触发
我们可以建立一个全局变量
const isComposing = ref(false);
在handleCompositionStart和handleCompositionEnd的事件中更改这个全局变量
const handleCompositionStart = () => {isComposing.value = true;
};const handleCompositionEnd = (event: Event) => {isComposing.value = false;
};
在input事件中判断是否是中文输入法输入中的状态
const input = (event: Event) => {if (isComposing.value) {return;}const value = (event.target as HTMLInputElement).value;emit("update:modelValue", value);emit("change", value); // 添加此行代码
};
最后在handleCompositionEnd事件中添加如下代码:
const handleCompositionEnd = (event: Event) => {isComposing.value = false;const value = (event.target as HTMLInputElement).value;emit("update:modelValue", value);emit("change", value);
};
最后即可解决这个问题!
最后附上我封装的input组件(若觉得组件功能不完善,可以自行扩展组件)
MyInput.vue
<template><div class="input-wrapper" :class="{ 'is-focused': isFocused }"><span class="prefix"><slot name="prefix"></slot></span><input:type="type"@input="input":placeholder="placeholder":disabled="disabled":readonly="readonly":maxlength="maxlength"@focus="handleFocus"@blur="handleBlur"@compositionstart="handleCompositionStart"@compositionend="handleCompositionEnd"/><span class="suffix"><slot name="suffix"></slot></span></div>
</template><script setup lang="ts">
import { ref } from "vue";const isFocused = ref(false);
const isComposing = ref(false);const props = defineProps<{type?: string;modelValue: string;placeholder?: string;disabled?: boolean;readonly?: boolean;maxlength?: number;
}>();const handleFocus = () => {isFocused.value = true;
};const handleBlur = () => {isFocused.value = false;
};const emit = defineEmits<{(e: "update:modelValue", value: string): void;(e: "change", value: string): void;
}>();// 监听是否是中文输入事件
const handleCompositionStart = () => {isComposing.value = true;
};const handleCompositionEnd = (event: Event) => {isComposing.value = false;const value = (event.target as HTMLInputElement).value;emit("update:modelValue", value);emit("change", value);
};const input = (event: Event) => {if (isComposing.value) {return;}const value = (event.target as HTMLInputElement).value;emit("update:modelValue", value);emit("change", value);
};
</script><style scoped>
.input-wrapper {display: flex;align-items: center;justify-content: center;padding: 1px 11px;border-radius: 10px;box-shadow: 0 0 0 1px #b5b5b5 inset;
}
.input-wrapper.is-focused {box-shadow: 0 0 0 2px #2478f2 inset;
}
input {width: 100%;flex-grow: 1;padding: 0;outline: 0;border: none;background: 0 0;box-sizing: border-box;outline: 0;font-size: 14px;line-height: 30px;
}input:disabled {background-color: #000000;cursor: not-allowed;
}input[readonly] {background-color: #000000;cursor: default;
}
.prefix {margin-right: 8px;
}
.suffix {margin-left: 8px;
}
</style>