diff --git a/.gitignore b/.gitignore index 2b1fdcb6..60c53fb4 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,4 @@ yarn-error.log* .oxlintrc.json.bak */**/auto-imports.d.ts */**/components.d.ts +.cunzhi* diff --git a/apps/docs/en/components/mentionSender/demos/header.vue b/apps/docs/en/components/mentionSender/demos/header.vue index d726b27e..618cf3b1 100644 --- a/apps/docs/en/components/mentionSender/demos/header.vue +++ b/apps/docs/en/components/mentionSender/demos/header.vue @@ -5,39 +5,36 @@ title: Header Slot Use the `#header` slot to customize the input header content. -::: info -Control header container expand/collapse through component instance +::: warning Deprecation Warning +The following methods will be removed in the next major version. It is recommended to use `v-model:openHeader` for two-way binding control: -- `senderRef.value.openHeader()` Open header container -- `senderRef.value.closeHeader()` Close header container +- `senderRef.value.openHeader()` Open header container (deprecated) +- `senderRef.value.closeHeader()` Close header container (deprecated) +::: + +::: tip Recommended Usage +Use `v-model:openHeader` for two-way binding to control header display state: + +```vue + + + +``` ::: @@ -51,16 +48,14 @@ function closeHeader() { justify-content: space-between; " > - - {{ showHeaderFlog ? 'Close Header' : 'Open Header' }} + + {{ openHeader ? 'Close Header' : 'Open Header' }} - + diff --git a/apps/docs/en/components/mentionSender/index.md b/apps/docs/en/components/mentionSender/index.md index 53b45536..4cbd93b6 100644 --- a/apps/docs/en/components/mentionSender/index.md +++ b/apps/docs/en/components/mentionSender/index.md @@ -142,6 +142,7 @@ This warm tip was last updated: `2025-04-16` | ------------------------- | -------------------- | -------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `v-model` | String | No | '' | Bound value of the input box, use `v-model` for two-way binding. | | `placeholder` | String | No | '' | Placeholder text for the input box. | +| `openHeader` | Boolean | No | false | Whether to open the custom header of the input box, using `v-model:openHeader` for two-way binding | | `auto-size` | Object | No | \{ minRows:1, maxRows:6 \} | Set the minimum and maximum number of visible rows for the input box. | | `read-only` | Boolean | No | false | Whether the input box is read-only. | | `disabled` | Boolean | No | false | Whether the input box is disabled. | diff --git a/apps/docs/en/components/sender/demos/header.vue b/apps/docs/en/components/sender/demos/header.vue index 33ae33c8..404bc867 100644 --- a/apps/docs/en/components/sender/demos/header.vue +++ b/apps/docs/en/components/sender/demos/header.vue @@ -5,39 +5,36 @@ title: Header Slot Use the `#header` slot to customize the input header content. -::: info -Control header container expand/collapse through component instance +::: warning Deprecation Warning +The following methods will be removed in the next major version. It is recommended to use `v-model:openHeader` for two-way binding control: -- `senderRef.value.openHeader()` Open header container -- `senderRef.value.closeHeader()` Close header container +- `senderRef.value.openHeader()` Open header container (deprecated) +- `senderRef.value.closeHeader()` Close header container (deprecated) +::: + +::: tip Recommended Usage +Use `v-model:openHeader` for two-way binding to control header display state: + +```vue + + + +``` ::: @@ -51,16 +48,14 @@ function closeHeader() { justify-content: space-between; " > - - {{ showHeaderFlog ? 'Close Header' : 'Open Header' }} + + {{ openHeader ? 'Close Header' : 'Open Header' }} - + diff --git a/apps/docs/en/components/sender/index.md b/apps/docs/en/components/sender/index.md index 683ce246..5732a952 100644 --- a/apps/docs/en/components/sender/index.md +++ b/apps/docs/en/components/sender/index.md @@ -2,7 +2,6 @@ title: Sender --- - ::: warning `Added in version 1.1.6` @@ -101,6 +100,7 @@ Built-in browser speech recognition API. You can use the [`useRecord`](https://e | ------------------------- | -------------------- | -------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `v-model` | String | No | '' | Bound value of the input box, use `v-model` for two-way binding. | | `placeholder` | String | No | '' | Placeholder text for the input box. | +| `openHeader` | Boolean | No | false | Whether to open the custom header of the input box, using `v-model:openHeader` for two-way binding | | `auto-size` | Object | No | \{ minRows:1, maxRows:6 \} | Set the minimum and maximum number of visible rows for the input box. | | `read-only` | Boolean | No | false | Whether the input box is read-only. | | `disabled` | Boolean | No | false | Whether the input box is disabled. | diff --git a/apps/docs/zh/components/mentionSender/demos/header.vue b/apps/docs/zh/components/mentionSender/demos/header.vue index f97381c0..4054f1c9 100644 --- a/apps/docs/zh/components/mentionSender/demos/header.vue +++ b/apps/docs/zh/components/mentionSender/demos/header.vue @@ -5,39 +5,36 @@ title: 头部插槽 通过 `#header` 插槽用于自定义输入框的头部内容。 -::: info -通过组件实例控制 头部容器 展开收起 +::: warning 废弃警告 +以下方法将在下个大版本中移除,推荐使用 `v-model:openHeader` 进行双向绑定控制: -- `senderRef.value.openHeader()` 打开头部容器 -- `senderRef.value.closeHeader()` 关闭头部容器 +- `senderRef.value.openHeader()` 打开头部容器 (已废弃) +- `senderRef.value.closeHeader()` 关闭头部容器 (已废弃) +::: + +::: tip 推荐用法 +使用 `v-model:openHeader` 进行双向绑定控制头部显示状态: + +```vue + + + +``` ::: @@ -51,16 +48,14 @@ function closeHeader() { justify-content: space-between; " > - - {{ showHeaderFlog ? '关闭头部' : '打开头部' }} + + {{ openHeader ? '关闭头部' : '打开头部' }} - + diff --git a/apps/docs/zh/components/mentionSender/index.md b/apps/docs/zh/components/mentionSender/index.md index edca877e..ecfe84b6 100644 --- a/apps/docs/zh/components/mentionSender/index.md +++ b/apps/docs/zh/components/mentionSender/index.md @@ -142,6 +142,7 @@ title: 'MentionSender' | ------------------------- | -------------------- | -------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `v-model` | String | 否 | '' | 输入框的绑定值,使用 `v-model` 进行双向绑定。 | | `placeholder` | String | 否 | '' | 输入框的提示语文本。 | +| `openHeader` | Boolean | 否 | false | 输入框自定义头部是否打开,使用 `v-model:openHeader` 进行双向绑定 | | `auto-size` | Object | 否 | \{ minRows:1, maxRows:6 \} | 设置输入框的最小展示行数和最大展示行数。 | | `read-only` | Boolean | 否 | false | 输入框是否为只读状态。 | | `disabled` | Boolean | 否 | false | 输入框是否为禁用状态。 | diff --git a/apps/docs/zh/components/sender/demos/header.vue b/apps/docs/zh/components/sender/demos/header.vue index d1fa7c52..ad8b87ee 100644 --- a/apps/docs/zh/components/sender/demos/header.vue +++ b/apps/docs/zh/components/sender/demos/header.vue @@ -5,39 +5,36 @@ title: 头部插槽 通过 `#header` 插槽用于自定义输入框的头部内容。 -::: info -通过组件实例控制 头部容器 展开收起 +::: warning 废弃警告 +以下方法将在下个大版本中移除,推荐使用 `v-model:openHeader` 进行双向绑定控制: -- `senderRef.value.openHeader()` 打开头部容器 -- `senderRef.value.closeHeader()` 关闭头部容器 +- `senderRef.value.openHeader()` 打开头部容器 (已废弃) +- `senderRef.value.closeHeader()` 关闭头部容器 (已废弃) +::: + +::: tip 推荐用法 +使用 `v-model:openHeader` 进行双向绑定控制头部显示状态: + +```vue + + + +``` ::: @@ -51,16 +48,14 @@ function closeHeader() { justify-content: space-between; " > - - {{ showHeaderFlog ? '关闭头部' : '打开头部' }} + + {{ openHeader ? '关闭头部' : '打开头部' }} - + diff --git a/apps/docs/zh/components/sender/index.md b/apps/docs/zh/components/sender/index.md index 5582181d..37660eb1 100644 --- a/apps/docs/zh/components/sender/index.md +++ b/apps/docs/zh/components/sender/index.md @@ -100,6 +100,7 @@ title: 'Sender' | ------------------------- | -------------------- | -------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `v-model` | String | 否 | '' | 输入框的绑定值,使用 `v-model` 进行双向绑定。 | | `placeholder` | String | 否 | '' | 输入框的提示语文本。 | +| `openHeader` | Boolean | 否 | false | 输入框自定义头部是否打开,使用 `v-model:openHeader` 进行双向绑定本。 | | `auto-size` | Object | 否 | \{ minRows:1, maxRows:6 \} | 设置输入框的最小展示行数和最大展示行数。 | | `read-only` | Boolean | 否 | false | 输入框是否为只读状态。 | | `disabled` | Boolean | 否 | false | 输入框是否为禁用状态。 | diff --git a/packages/core/components.d.ts b/packages/core/components.d.ts index 829d2fd7..eeb83ad7 100644 --- a/packages/core/components.d.ts +++ b/packages/core/components.d.ts @@ -35,7 +35,6 @@ declare module 'vue' { ElIcon: typeof import('element-plus/es')['ElIcon'] ElImage: typeof import('element-plus/es')['ElImage'] ElInput: typeof import('element-plus/es')['ElInput'] - ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] ElMention: typeof import('element-plus/es')['ElMention'] ElPopover: typeof import('element-plus/es')['ElPopover'] ElProgress: typeof import('element-plus/es')['ElProgress'] @@ -54,7 +53,6 @@ declare module 'vue' { Image: typeof import('./src/components/FilesCard/fileSvg/image.vue')['default'] IndexAttachments: typeof import('./src/components/Attachments/index-attachments.vue')['default'] IndexFileList: typeof import('./src/components/Attachments/index-file-list.vue')['default'] - IndexOri: typeof import('./src/components/XMarkdownCore/components/CodeBlock/index-ori.vue')['default'] Item: typeof import('./src/components/Conversations/components/item.vue')['default'] Link: typeof import('./src/components/FilesCard/fileSvg/link.vue')['default'] Loading: typeof import('./src/components/BubbleList/loading.vue')['default'] diff --git a/packages/core/src/components/MentionSender/index.vue b/packages/core/src/components/MentionSender/index.vue index 5348856c..547258a5 100644 --- a/packages/core/src/components/MentionSender/index.vue +++ b/packages/core/src/components/MentionSender/index.vue @@ -30,6 +30,9 @@ const props = withDefaults(defineProps(), { // el-input 属性透传 inputStyle: '', + // 头部显示控制 + openHeader: false, + // el-mention 属性透传 options: () => [], filterOption: () => true, @@ -51,8 +54,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); } }); @@ -95,22 +97,52 @@ function onContentMouseDown(e: MouseEvent) { /* 内容容器聚焦 结束 */ /* 头部显示隐藏 开始 */ -const visiableHeader = ref(false); +// 内部状态,用于没有外部绑定时的状态管理 +const internalHeaderOpen = ref(props.openHeader); + +// 监听 props.openHeader 变化,同步到内部状态 +watch( + () => props.openHeader, + newValue => { + internalHeaderOpen.value = newValue; + } +); + +const headerOpenState = computed({ + get() { + return internalHeaderOpen.value; + }, + set(value) { + if (props.readOnly || props.disabled) return; + + internalHeaderOpen.value = value; + // 始终触发更新事件,让外部可以监听状态变化 + emits('update:openHeader', value); + } +}); + +/** + * 打开头部容器 + * @deprecated 此方法将在下个大版本中移除,请使用 v-model:openHeader 代替 + * @returns {boolean} 是否成功打开 + */ 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; + headerOpenState.value = true; + return true; } + +/** + * 关闭头部容器 + * @deprecated 此方法将在下个大版本中移除,请使用 v-model:openHeader 代替 + */ function closeHeader() { - if (!slots.header) - return; - if (props.readOnly) - return; - visiableHeader.value = false; + if (!slots.header) return; + if (props.readOnly) return; + headerOpenState.value = false; } /* 头部显示隐藏 结束 */ @@ -119,8 +151,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); @@ -151,8 +182,7 @@ function startRecognition() { speechLoading.value = false; }; recognition.value.start(); - } - else { + } else { console.error('浏览器不支持 Web Speech API'); } } @@ -185,22 +215,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.input.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); // 光标前的文本 @@ -231,8 +258,7 @@ function handleKeyDown(e: { target: HTMLTextAreaElement } & KeyboardEvent) { e.preventDefault(); if (props.submitType === 'enter') { _isComKeyDown ? _resetSelectionRange() : submit(); - } - else { + } else { _isComKeyDown ? submit() : _resetSelectionRange(); } } @@ -253,11 +279,9 @@ function focus(type = 'all') { } if (type === 'all') { inputRef.value.input.select(); - } - else if (type === 'start') { + } else if (type === 'start') { focusToStart(); - } - else if (type === 'end') { + } else if (type === 'end') { focusToEnd(); } } @@ -309,8 +333,8 @@ function handleInternalPaste(e: ClipboardEvent) { } defineExpose({ - openHeader, // 打开头部 - closeHeader, // 关闭头部 + openHeader, // 打开头部 (已废弃,请使用 v-model:openHeader) + closeHeader, // 关闭头部 (已废弃,请使用 v-model:openHeader) clear, // 清空输入框 blur, // 失去焦点 focus, // 获取焦点 @@ -345,7 +369,7 @@ defineExpose({ > -
+
diff --git a/packages/core/src/components/MentionSender/types.d.ts b/packages/core/src/components/MentionSender/types.d.ts index bd32caf8..1395e251 100644 --- a/packages/core/src/components/MentionSender/types.d.ts +++ b/packages/core/src/components/MentionSender/types.d.ts @@ -29,6 +29,9 @@ export interface MentionSenderProps { // 新增 el-input 样式透传 inputStyle?: string | CSSProperties | CSSProperties[] | string[]; + // 头部显示控制 + openHeader?: boolean; // 头部是否打开 + // 提及选项列表 options?: MentionOption[]; // 定制筛选器选项逻辑 @@ -52,6 +55,7 @@ export interface MentionSenderProps { export interface MentionSenderEmits { // 双向绑定相关事件 (event: 'update:modelValue', value: string): void; + (event: 'update:openHeader', open: boolean): void; // 操作事件 (event: 'submit', internalValue: string): void; (event: 'cancel', internalValue: string): void; diff --git a/packages/core/src/components/Sender/index.vue b/packages/core/src/components/Sender/index.vue index 75f869f2..0c18df57 100644 --- a/packages/core/src/components/Sender/index.vue +++ b/packages/core/src/components/Sender/index.vue @@ -26,6 +26,9 @@ const props = withDefaults(defineProps(), { // el-input 属性透传 inputStyle: () => {}, + // 头部显示控制 + openHeader: false, + triggerStrings: () => [], // 指令字符数组,默认空数组 triggerPopoverVisible: false, triggerPopoverWidth: 'fit-content', @@ -56,8 +59,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 +89,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 +101,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 +120,7 @@ watch( isOpen: true }); popoverVisible.value = true; - } - else { + } else { popoverVisible.value = true; } } @@ -135,8 +134,7 @@ watch( isOpen: false }); popoverVisible.value = false; - } - else { + } else { popoverVisible.value = false; } } @@ -151,8 +149,7 @@ watch( isOpen: true }); popoverVisible.value = true; - } - else { + } else { popoverVisible.value = true; } } @@ -171,22 +168,52 @@ function onContentMouseDown(e: MouseEvent) { /* 内容容器聚焦 结束 */ /* 头部显示隐藏 开始 */ -const visiableHeader = ref(false); +// 内部状态,用于没有外部绑定时的状态管理 +const internalHeaderOpen = ref(props.openHeader); + +// 监听 props.openHeader 变化,同步到内部状态 +watch( + () => props.openHeader, + newValue => { + internalHeaderOpen.value = newValue; + } +); + +const headerOpenState = computed({ + get() { + return internalHeaderOpen.value; + }, + set(value) { + if (props.readOnly || props.disabled) return; + + internalHeaderOpen.value = value; + // 始终触发更新事件,让外部可以监听状态变化 + emits('update:openHeader', value); + } +}); + +/** + * 打开头部容器 + * @deprecated 此方法将在下个大版本中移除,请使用 v-model:openHeader 代替 + * @returns {boolean} 是否成功打开 + */ 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; + headerOpenState.value = true; + return true; } + +/** + * 关闭头部容器 + * @deprecated 此方法将在下个大版本中移除,请使用 v-model:openHeader 代替 + */ function closeHeader() { - if (!slots.header) - return; - if (props.readOnly) - return; - visiableHeader.value = false; + if (!slots.header) return; + if (props.readOnly) return; + headerOpenState.value = false; } /* 头部显示隐藏 结束 */ @@ -195,8 +222,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 +253,7 @@ function startRecognition() { speechLoading.value = false; }; recognition.value.start(); - } - else { + } else { console.error('浏览器不支持 Web Speech API'); } } @@ -261,22 +286,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 +329,7 @@ function handleKeyDown(e: { target: HTMLTextAreaElement } & KeyboardEvent) { e.preventDefault(); if (props.submitType === 'enter') { _isComKeyDown ? _resetSelectionRange() : submit(); - } - else { + } else { _isComKeyDown ? submit() : _resetSelectionRange(); } } @@ -329,11 +350,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(); } } @@ -384,8 +403,8 @@ function handleInternalPaste(e: ClipboardEvent) { } defineExpose({ - openHeader, // 打开头部 - closeHeader, // 关闭头部 + openHeader, // 打开头部 (已废弃,请使用 v-model:openHeader) + closeHeader, // 关闭头部 (已废弃,请使用 v-model:openHeader) clear, // 清空输入框 blur, // 失去焦点 focus, // 获取焦点 @@ -424,7 +443,7 @@ defineExpose({ > -
+
diff --git a/packages/core/src/components/Sender/types.d.ts b/packages/core/src/components/Sender/types.d.ts index a88814fe..8fd4c6e1 100644 --- a/packages/core/src/components/Sender/types.d.ts +++ b/packages/core/src/components/Sender/types.d.ts @@ -22,6 +22,9 @@ export interface SenderProps { // 新增 el-input 样式透传 inputStyle?: string | CSSProperties | CSSProperties[] | string[]; + // 头部显示控制 + openHeader?: boolean; // 头部是否打开 + // 新增 el-popover 样式透传 triggerStrings?: string[]; triggerPopoverVisible?: boolean; // 指令提示框是否可见 @@ -54,6 +57,7 @@ export interface SenderEmits { // 双向绑定相关事件 (event: 'update:modelValue', value: string): void; (event: 'update:triggerPopoverVisible', visible: boolean): void; + (event: 'update:openHeader', open: boolean): void; // 操作事件 (event: 'submit', internalValue: string): void; (event: 'cancel', internalValue: string): void; diff --git a/packages/core/src/stories/MentionSender/CustomSolt.vue b/packages/core/src/stories/MentionSender/CustomSolt.vue index a7dbd794..75a75128 100644 --- a/packages/core/src/stories/MentionSender/CustomSolt.vue +++ b/packages/core/src/stories/MentionSender/CustomSolt.vue @@ -6,13 +6,11 @@ import { MentionSender } from '../../components'; const senderRef = ref>(); -const showHeaderFlog = ref(false); +const openHeader = ref(true); // 使用 v-model:openHeader 控制头部显示状态 const valueStr = computed(() => senderRef.value?.$props.modelValue); onMounted(() => { - showHeaderFlog.value = true; - senderRef.value?.openHeader(); window.addEventListener('keydown', handleWindowKeydown); nextTick(() => { @@ -39,18 +37,11 @@ function focus(type = 'all') { senderRef.value?.focus(type); } function openCloseHeader() { - if (!showHeaderFlog.value) { - senderRef.value?.openHeader(); - } - else { - senderRef.value?.closeHeader(); - } - showHeaderFlog.value = !showHeaderFlog.value; + openHeader.value = !openHeader.value; } function closeHeader() { - showHeaderFlog.value = false; - senderRef.value?.closeHeader(); + openHeader.value = false; } function handleSubmit(value: string) { @@ -130,7 +121,7 @@ function handleInputKeydown(e: KeyboardEvent) { 使用组件实例取消
-
+
文本最前方 @@ -145,10 +136,11 @@ function handleInputKeydown(e: KeyboardEvent) { 失去焦点
-
+
-
- 💯 欢迎使用 Element Plus X -
+
💯 欢迎使用 Element Plus X
@@ -180,9 +170,7 @@ function handleInputKeydown(e: KeyboardEvent) {
-
- 🦜 自定义头部内容 -
+
🦜 自定义头部内容
diff --git a/packages/core/src/stories/MentionSender/MentionSender.stories.ts b/packages/core/src/stories/MentionSender/MentionSender.stories.ts index 6c2f85f0..2ccc6542 100644 --- a/packages/core/src/stories/MentionSender/MentionSender.stories.ts +++ b/packages/core/src/stories/MentionSender/MentionSender.stories.ts @@ -19,6 +19,14 @@ const meta: Meta = { control: 'text', description: '输入框的提示语文本。' }, + openHeader: { + defaultValue: false, + control: 'boolean', + description: + '输入框自定义头部是否打开的绑定值,使用 v-model 进行双向绑定', + // 隐藏 openHeader 属性 不能使用 需要CustomSolt组件不使用v-model:openHeader + table: { disable: true } + }, autoSize: { defaultValue: { minRows: 1, maxRows: 6 }, control: 'object', @@ -124,6 +132,7 @@ const meta: Meta = { args: { modelValue: '', placeholder: '请输入内容', + openHeader: false, autoSize: { minRows: 1, maxRows: 5 diff --git a/packages/core/src/stories/Sender/CustomSolt.vue b/packages/core/src/stories/Sender/CustomSolt.vue index 1f72f309..b6dad40a 100644 --- a/packages/core/src/stories/Sender/CustomSolt.vue +++ b/packages/core/src/stories/Sender/CustomSolt.vue @@ -7,13 +7,11 @@ import { Sender } from '../../components'; const senderRef = ref>(); -const showHeaderFlog = ref(false); +const openHeader = ref(true); // 使用 v-model:openHeader 控制头部显示状态 const valueStr = computed(() => senderRef.value?.$props.modelValue); onMounted(() => { - showHeaderFlog.value = true; - senderRef.value?.openHeader(); window.addEventListener('keydown', handleWindowKeydown); senderRef.value?.inputInstance.addEventListener( 'keydown', @@ -37,18 +35,11 @@ function focus(type = 'all') { senderRef.value?.focus(type); } function openCloseHeader() { - if (!showHeaderFlog.value) { - senderRef.value?.openHeader(); - } - else { - senderRef.value?.closeHeader(); - } - showHeaderFlog.value = !showHeaderFlog.value; + openHeader.value = !openHeader.value; } function closeHeader() { - showHeaderFlog.value = false; - senderRef.value?.closeHeader(); + openHeader.value = false; } function handleSubmit(value: string) { @@ -125,7 +116,7 @@ function handleInputKeydown(e: KeyboardEvent) { 使用组件实例取消
-
+
文本最前方 @@ -140,10 +131,11 @@ function handleInputKeydown(e: KeyboardEvent) { 失去焦点
-
+
-
- 💯 欢迎使用 Element Plus X -
+
💯 欢迎使用 Element Plus X
@@ -174,9 +164,7 @@ function handleInputKeydown(e: KeyboardEvent) {
-
- 🦜 自定义头部内容 -
+
🦜 自定义头部内容
diff --git a/packages/core/src/stories/Sender/Sender.stories.ts b/packages/core/src/stories/Sender/Sender.stories.ts index 18ff8417..98dfbf5e 100644 --- a/packages/core/src/stories/Sender/Sender.stories.ts +++ b/packages/core/src/stories/Sender/Sender.stories.ts @@ -19,6 +19,14 @@ const meta: Meta = { control: 'text', description: '输入框的提示语文本。' }, + openHeader: { + defaultValue: false, + control: 'boolean', + description: + '输入框自定义头部是否打开的绑定值,使用 v-model 进行双向绑定', + // 隐藏 openHeader 属性 不能使用需要CustomSolt组件不使用v-model:openHeader + table: { disable: true } + }, autoSize: { defaultValue: { minRows: 1, maxRows: 6 }, control: 'object', @@ -135,6 +143,7 @@ const meta: Meta = { args: { modelValue: '', placeholder: '请输入内容', + openHeader: false, autoSize: { minRows: 1, maxRows: 5 @@ -192,6 +201,7 @@ export const SenderDemo: Story = { `