From 19362fadf73f835195ff50533288ad278cce9019 Mon Sep 17 00:00:00 2001
From: sakurayinfei <970412446@qq.com>
Date: Mon, 28 Apr 2025 10:51:47 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DOInput=E5=8F=8AOTextar?=
=?UTF-8?q?ea=E5=9C=A8=E5=8F=91=E9=80=81=E9=AA=8C=E8=AF=81=E7=A0=81?=
=?UTF-8?q?=E8=AF=BB=E7=A7=92=E7=AD=89=E5=9C=BA=E6=99=AF=E4=B8=AD=EF=BC=8C?=
=?UTF-8?q?=E6=97=A0=E6=B3=95=E4=BD=BF=E7=94=A8=E8=BE=93=E5=85=A5=E6=B3=95?=
=?UTF-8?q?=E8=BE=93=E5=85=A5=E5=86=85=E5=AE=B9=E7=9A=84bug?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/_components/in-input/InInput.vue | 10 +-
.../_components/in-textarea/InTextarea.vue | 4 +-
packages/opendesign/src/directives/index.ts | 1 +
packages/opendesign/src/directives/o-model.ts | 25 +++++
.../opendesign/src/hooks/use-composition.ts | 8 +-
.../src/input/__demo__/InputVerification.vue | 15 +--
.../__demo__/TextareaVerification.vue | 94 +++++++++++++++++++
.../src/textarea/__demo__/TheIndex.vue | 2 +
8 files changed, 144 insertions(+), 15 deletions(-)
create mode 100644 packages/opendesign/src/directives/o-model.ts
create mode 100644 packages/opendesign/src/textarea/__demo__/TextareaVerification.vue
diff --git a/packages/opendesign/src/_components/in-input/InInput.vue b/packages/opendesign/src/_components/in-input/InInput.vue
index 61ccfc54..e2f68eeb 100644
--- a/packages/opendesign/src/_components/in-input/InInput.vue
+++ b/packages/opendesign/src/_components/in-input/InInput.vue
@@ -5,6 +5,7 @@ import { IconClose, IconEyeOn, IconEyeOff } from '../../_utils/icons';
import { useInput, type UseInputEmitsT } from '../../_headless/use-input';
import { useInputPassword } from '../../_headless/use-input-password';
import { useI18n } from '../../locale';
+import { vOModel } from '../../directives';
const props = defineProps(inInputProps);
const slots = defineSlots<{
@@ -110,18 +111,23 @@ defineExpose({
diff --git a/packages/opendesign/src/directives/index.ts b/packages/opendesign/src/directives/index.ts
index d92e7281..4bdb6a03 100644
--- a/packages/opendesign/src/directives/index.ts
+++ b/packages/opendesign/src/directives/index.ts
@@ -3,3 +3,4 @@ export * from './focus';
export * from './on-intersection';
export * from './on-resize';
export * from './uid';
+export * from './o-model';
diff --git a/packages/opendesign/src/directives/o-model.ts b/packages/opendesign/src/directives/o-model.ts
new file mode 100644
index 00000000..d987b67c
--- /dev/null
+++ b/packages/opendesign/src/directives/o-model.ts
@@ -0,0 +1,25 @@
+import { type ObjectDirective } from 'vue';
+
+export const vOModel: ObjectDirective
= {
+ created(el, { value }) {
+ const { handleInput } = value;
+ if (typeof handleInput !== 'function') {
+ throw new Error('v-o-model: handleInput is not a function');
+ }
+ el.addEventListener('input', handleInput);
+ },
+ mounted(el, { value }) {
+ const { modelValue } = value;
+ el.value = modelValue == null ? '' : modelValue;
+ },
+ beforeUpdate(el, { value }) {
+ if ((el as any).composing) {
+ return;
+ }
+ const { modelValue } = value;
+ if (el.value === modelValue) {
+ return;
+ }
+ el.value = modelValue == null ? '' : modelValue;
+ },
+};
diff --git a/packages/opendesign/src/hooks/use-composition.ts b/packages/opendesign/src/hooks/use-composition.ts
index a91c78e0..9500de3a 100644
--- a/packages/opendesign/src/hooks/use-composition.ts
+++ b/packages/opendesign/src/hooks/use-composition.ts
@@ -5,8 +5,10 @@ export function useComposition({ el }: { el?: Ref } = {
const isComposing = ref(false);
// 开始中文输入
- const onCompositionStart = () => {
+ const onCompositionStart = (e: Event) => {
isComposing.value = true;
+ // e.target.composing 会在 vOModel 中使用
+ (e.target as any).composing = true;
};
// 结束中文输入
const onCompositionEnd = (e: Event) => {
@@ -15,6 +17,7 @@ export function useComposition({ el }: { el?: Ref } = {
}
isComposing.value = false;
+ (e.target as any).composing = false;
trigger(e.target as HTMLElement, 'input');
};
@@ -24,6 +27,9 @@ export function useComposition({ el }: { el?: Ref } = {
}
el.value.addEventListener('compositionstart', onCompositionStart);
el.value.addEventListener('compositionend', onCompositionEnd);
+ // Safari < 10.2 & UIWebView 在确认输入法选项前切换焦点时不会触发 compositionend 事件;
+ // 同时解决了某些浏览器(如 iOS Chrome)在自动填充时触发"change"事件而非"input"事件的问题。
+ el.value.addEventListener('change', onCompositionEnd);
});
onUnmounted(() => {
diff --git a/packages/opendesign/src/input/__demo__/InputVerification.vue b/packages/opendesign/src/input/__demo__/InputVerification.vue
index 874104ef..3d064453 100644
--- a/packages/opendesign/src/input/__demo__/InputVerification.vue
+++ b/packages/opendesign/src/input/__demo__/InputVerification.vue
@@ -1,9 +1,7 @@
+
+ 验证码输入框
+ 验证码: 1234
+
+
+
+
+
+ {{ sendLabel }}
+
+
+
+
验证通过
+
+
+
+
diff --git a/packages/opendesign/src/textarea/__demo__/TheIndex.vue b/packages/opendesign/src/textarea/__demo__/TheIndex.vue
index 68af36de..5af2dba3 100644
--- a/packages/opendesign/src/textarea/__demo__/TheIndex.vue
+++ b/packages/opendesign/src/textarea/__demo__/TheIndex.vue
@@ -5,12 +5,14 @@ import '../../option/style';
import TextareaBasic from './TextareaBasic.vue';
import TextareaAutoHeight from './TextareaAutoHeight.vue';
import TextareaSlot from './TextareaSlot.vue';
+import TextareaVerification from './TextareaVerification.vue';
+
--
Gitee