From 395c48a8fcb00906115451e06944a94e3243e60f Mon Sep 17 00:00:00 2001 From: zhangzhen Date: Tue, 16 Sep 2025 10:40:38 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix(Sender):=20=E5=A2=9E=E5=8A=A0=20Sender?= =?UTF-8?q?=20=E7=BB=84=E4=BB=B6=E5=A2=9E=E5=8A=A0=E5=B1=9E=E6=80=A7=20min?= =?UTF-8?q?length=E3=80=81maxlength?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closed #263 --- packages/core/src/components/Sender/index.vue | 56 +++++++------------ .../core/src/components/Sender/types.d.ts | 4 ++ .../core/src/stories/Sender/Sender.stories.ts | 8 +++ 3 files changed, 32 insertions(+), 36 deletions(-) diff --git a/packages/core/src/components/Sender/index.vue b/packages/core/src/components/Sender/index.vue index 75f869f2..670c19a0 100644 --- a/packages/core/src/components/Sender/index.vue +++ b/packages/core/src/components/Sender/index.vue @@ -14,6 +14,8 @@ const props = withDefaults(defineProps(), { minRows: 1, maxRows: 6 }), + minlength: undefined, + maxlength: undefined, submitType: 'enter', headerAnimationTimer: 300, inputWidth: '100%', @@ -56,8 +58,7 @@ const internalValue = computed({ return props.modelValue; }, set(val) { - if (props.readOnly || props.disabled) - return; + if (props.readOnly || props.disabled) return; emits('update:modelValue', val); } }); @@ -87,8 +88,7 @@ const popoverVisible = computed({ return props.triggerPopoverVisible; }, set(value) { - if (props.readOnly || props.disabled) - return; + if (props.readOnly || props.disabled) return; emits('update:triggerPopoverVisible', value); } }); @@ -100,8 +100,7 @@ const triggerString = ref(''); watch( () => internalValue.value, (newVal, oldVal) => { - if (isComposing.value) - return; + if (isComposing.value) return; // 触发逻辑:当输入值等于数组中的任意一个指令字符时触发 // 确保 oldVal 是字符串类型 const triggerStrings = props.triggerStrings || []; // 如果为 undefined,就使用空数组 @@ -120,8 +119,7 @@ watch( isOpen: true }); popoverVisible.value = true; - } - else { + } else { popoverVisible.value = true; } } @@ -135,8 +133,7 @@ watch( isOpen: false }); popoverVisible.value = false; - } - else { + } else { popoverVisible.value = false; } } @@ -151,8 +148,7 @@ watch( isOpen: true }); popoverVisible.value = true; - } - else { + } else { popoverVisible.value = true; } } @@ -173,19 +169,15 @@ function onContentMouseDown(e: MouseEvent) { /* 头部显示隐藏 开始 */ const visiableHeader = ref(false); function openHeader() { - if (!slots.header) - return false; + if (!slots.header) return false; - if (props.readOnly) - return false; + if (props.readOnly) return false; visiableHeader.value = true; } function closeHeader() { - if (!slots.header) - return; - if (props.readOnly) - return; + if (!slots.header) return; + if (props.readOnly) return; visiableHeader.value = false; } /* 头部显示隐藏 结束 */ @@ -195,8 +187,7 @@ const recognition = ref(null); const speechLoading = ref(false); function startRecognition() { - if (props.readOnly) - return; // 直接返回,不执行后续逻辑 + if (props.readOnly) return; // 直接返回,不执行后续逻辑 if (hasOnRecordingChangeListener.value) { speechLoading.value = true; emits('recordingChange', true); @@ -227,8 +218,7 @@ function startRecognition() { speechLoading.value = false; }; recognition.value.start(); - } - else { + } else { console.error('浏览器不支持 Web Speech API'); } } @@ -261,22 +251,19 @@ function submit() { } // 取消按钮 function cancel() { - if (props.readOnly) - return; + if (props.readOnly) return; emits('cancel', internalValue.value); } function clear() { - if (props.readOnly) - return; // 直接返回,不执行后续逻辑 + if (props.readOnly) return; // 直接返回,不执行后续逻辑 inputRef.value.clear(); internalValue.value = ''; } // 在这判断组合键的回车键 (目前支持四种模式) function handleKeyDown(e: { target: HTMLTextAreaElement } & KeyboardEvent) { - if (props.readOnly) - return; // 直接返回,不执行后续逻辑 + if (props.readOnly) return; // 直接返回,不执行后续逻辑 const _resetSelectionRange = () => { const cursorPosition = e.target.selectionStart; // 获取光标位置 const textBeforeCursor = internalValue.value.slice(0, cursorPosition); // 光标前的文本 @@ -307,8 +294,7 @@ function handleKeyDown(e: { target: HTMLTextAreaElement } & KeyboardEvent) { e.preventDefault(); if (props.submitType === 'enter') { _isComKeyDown ? _resetSelectionRange() : submit(); - } - else { + } else { _isComKeyDown ? submit() : _resetSelectionRange(); } } @@ -329,11 +315,9 @@ function focus(type = 'all') { } if (type === 'all') { inputRef.value.select(); - } - else if (type === 'start') { + } else if (type === 'start') { focusToStart(); - } - else if (type === 'end') { + } else if (type === 'end') { focusToEnd(); } } diff --git a/packages/core/src/components/Sender/types.d.ts b/packages/core/src/components/Sender/types.d.ts index a88814fe..95ecfe40 100644 --- a/packages/core/src/components/Sender/types.d.ts +++ b/packages/core/src/components/Sender/types.d.ts @@ -5,6 +5,10 @@ export interface SenderProps { minRows: number; maxRows: number; }; + // 原生属性,最小输入长度 + minlength?: string | number; + // 同原生 maxlength 属性 + maxlength?: string | number; readOnly?: boolean; disabled?: boolean; loading?: boolean; diff --git a/packages/core/src/stories/Sender/Sender.stories.ts b/packages/core/src/stories/Sender/Sender.stories.ts index 18ff8417..62c8daa4 100644 --- a/packages/core/src/stories/Sender/Sender.stories.ts +++ b/packages/core/src/stories/Sender/Sender.stories.ts @@ -24,6 +24,14 @@ const meta: Meta = { control: 'object', description: '设置输入框的最小展示行数和最大展示行数。' }, + minlength: { + control: 'text', + description: '设置输入框的最小输入长度。' + }, + maxlength: { + control: 'text', + description: '设置输入框的最大输入长度。' + }, readOnly: { defaultValue: false, control: 'boolean', From 7dd5d57935c1d6ab2705c25e76ac4ba996830d7c Mon Sep 17 00:00:00 2001 From: zhangzhen Date: Tue, 16 Sep 2025 10:51:13 +0800 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20=E8=A1=A5=E5=85=85=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/components/Sender/index.vue | 2 ++ packages/core/src/stories/Sender/Sender.stories.ts | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/core/src/components/Sender/index.vue b/packages/core/src/components/Sender/index.vue index 670c19a0..38a03279 100644 --- a/packages/core/src/components/Sender/index.vue +++ b/packages/core/src/components/Sender/index.vue @@ -442,6 +442,8 @@ defineExpose({ :rows="1" :autosize="autoSize" type="textarea" + :minlength="minlength" + :maxlength="maxlength" :validate-event="false" :placeholder="placeholder" :read-only="readOnly || disabled" diff --git a/packages/core/src/stories/Sender/Sender.stories.ts b/packages/core/src/stories/Sender/Sender.stories.ts index 62c8daa4..40b10b1c 100644 --- a/packages/core/src/stories/Sender/Sender.stories.ts +++ b/packages/core/src/stories/Sender/Sender.stories.ts @@ -25,11 +25,13 @@ const meta: Meta = { description: '设置输入框的最小展示行数和最大展示行数。' }, minlength: { - control: 'text', + defaultValue: 0, + control: 'number', description: '设置输入框的最小输入长度。' }, maxlength: { - control: 'text', + defaultValue: 10, + control: 'number', description: '设置输入框的最大输入长度。' }, readOnly: { @@ -147,6 +149,8 @@ const meta: Meta = { minRows: 1, maxRows: 5 }, + minlength: 0, + maxlength: 10, readOnly: false, disabled: false, submitBtnDisabled: false,