Skip to content

Sender 消息输入框组件

Sender 是一个灵活的输入组件,支持多种输入方式和功能,包括文本输入、语音输入、模板填充等。具有丰富的功能和自定义选项。适用于聊天界面、评论输入、搜索框等多种场景。

代码示例

基础用法

单行模式(mode="single"), 适用于简单的输入场景,如搜索框、简短消息输入等。

  • 换行说明,在单行模式下

  • 1.输入文字超出单行宽度限制时,会自动切换至多行模式。

  • 2.使用快捷键组合 shift+enter 可以直接切换至多行模式

多行模式(mode="multiple")适用于较长文本输入,如评论、聊天消息等。

loading

状态控制

加载状态

通过设置loading属性控制组件的加载状态,加载状态下输入框将显示加载动画并禁用输入。 在加载状态下,点击加载图标可以取消发送操作,这会触发 cancel 事件。

vue
<tr-sender :loading="true" stopText="停止回答" />

禁用状态

通过设置disabled属性禁用整个组件,禁用状态下无法输入内容或触发任何操作。

vue
<tr-sender :disabled="true" />

内容控制

字数限制与统计

通过maxLength属性限制输入字符数,搭配showWordLimit显示字数统计。

注意:当输入内容超出字数限制时,系统不会自动截断,真实字数会以红色标示,且无法发送。

vue
<tr-sender mode="multiple" :showWordLimit="true" :maxLength="20" defaultValue="测试超出字数限制,当前已经超过了字数限制。"/>

自动调整高度

通过autoSize属性可以设置输入框是否自动调整高度。当设置为true时,输入框会根据内容自动调整高度,适用于需要动态适应内容长度的场景。

注意:只对 mode="multiple" 有效。

可传入对象,如{ minRows: 2, maxRows: 3 }。

loading

可清空输入

通过clearable属性添加清空按钮,方便用户快速清除输入内容。

vue
<tr-sender :clearable="true" />

高级功能

自定义按钮

Sender 组件支持在多行模式下灵活定制底部区域。通过 footer-leftfooter-right 插槽,您可以在保留现有功能的同时添加自定义内容。

  • footer-left: 在字数限制左侧添加自定义内容
  • footer-right: 在操作按钮左侧添加自定义内容
  • footer: 完全自定义底部区域(会覆盖默认内容,仅用于向后兼容)
loading

注意:footer 插槽与 footer-left/footer-right 插槽互斥,如果同时使用,将优先显示 footer-left/footer-right 插槽。

语音输入

启用allowSpeech支持语音输入功能,用户可以通过语音录入文本。

  • 混合模式:用户可以先用键盘输入部分内容,然后通过语音继续补充,自动停止录音。

  • 连续语音输入:用户可以连续录入语音,系统会自动将语音转换为文本,点击按钮手动停止录音。

loading

消息提示

此功能适用于需要在输入框内显示提示信息并引导用户操作的场景,如:

  • 1. 服务状态提示
  • 2. 快捷操作链接
  • 3. 功能引导等

当使用 decorativeContent 插槽时,输入框会自动被禁用,仅展示插槽内容,无法输入文本或触发发送操作。

loading

文件上传

支持附件上传功能,可通过allowFiles控制。

目前仅支持按钮显示,后续会添加附件上传相关功能。

vue
<tr-sender :allowFiles="true" />

模版填充

通过 templateData prop 实现模板的动态设置与双向绑定。推荐使用 v-model:templateData 的语法糖。

该功能加载后,光标会自动聚焦在第一个可编辑的模板字段上,方便用户直接开始编辑。

模板示例

loading

备注templateData prop 接收一个 UserItem[] 类型的数组。 UserItem 的结构为 { type: 'text', content: string }{ type: 'template', content: string }。 当 type'template' 时,对应的 content 会渲染为一个可编辑的模板字段。

输入联想

Sender 组件支持输入联想功能,当用户输入时,可以根据提供的 suggestions 列表显示匹配的建议项。此功能有助于提高输入效率和准确性。

核心特性:

  • Tab 提示器: 仅在有联想数据且输入框有内容时显示,提示用户可按 Tab 选择。

  • 输入框补全: 用户输入部分正常显示,联想到的补全部分以半透明灰色文本展示。

  • 键盘交互:

    • /: 在联想弹窗中导航。
    • Tab/Enter: 确认当前高亮的联想项。
    • Esc: 关闭联想弹窗。

注意: 输入框内的补全文本特性在匹配到联想项的前置字符时显示,否则不显示。

loading

自定义提交方式

通过submitType属性控制提交方式,支持多种键盘快捷键组合。

  • 提交行为说明:
    • 当 submitType 为 enter 时:按 Enter 键提交
    • 当 submitType 为 ctrlEnter 时:按 Ctrl+Enter 提交,单独按 Enter 换行
    • 当 submitType 为 shiftEnter 时:按 Shift+Enter 提交,单独按 Enter 换行

这些快捷键适用于不同的使用习惯和操作系统,方便用户根据自己的喜好选择提交方式。

vue
<tr-sender submitType="ctrlEnter" mode="multiple" placeholder="按Ctrl+Enter提交" />
vue
<tr-sender submitType="shiftEnter" mode="multiple" placeholder="按Shift+Enter提交" />

使用不同的提交方式可以适应不同的使用场景:

  • 聊天应用通常使用enter快速提交消息
  • 多行文本编辑时,使用ctrl+entershift+enter可避免误提交
  • 代码编辑器类应用通常使用ctrl+enter提交,保持编辑文本的结构

键盘快捷键支持

Sender 组件支持多种键盘快捷键操作,提高用户输入效率:

快捷键功能适用条件
Enter提交内容 / 选中联想项submitType="enter"(默认) / 联想弹窗开启时
Ctrl+Enter提交内容submitType="ctrlEnter"(多行)
Shift+Enter提交内容submitType="shiftEnter"(多行)
Tab选中联想项联想弹窗开启并有联想数据时
Esc取消语音/关闭联想/建议对应功能激活时
↑ / ↓导航联想项联想弹窗开启时

您可以在实际开发中根据应用场景和用户需求选择最适合的快捷键方式。

布局与插槽

以下是一个关于插槽的综合使用示例:

loading

紧凑模式配置

Sender 组件支持紧凑模式,适用于空间受限的场景。通过添加 tr-sender-compact CSS类可以启用紧凑样式。

紧凑模式的特点:

  • 较小的字体和输入框(14px vs 16px)
  • 更紧凑的内边距和间距
  • 更小的图标尺寸(32px vs 36px)
  • 更小的圆角(24px vs 26px)

使用方式:

vue
<!-- 默认样式(宽松模式) -->
<TrSender />

<!-- 紧凑模式 -->
<TrSender class="tr-sender-compact" />
loading

API 说明

Props

属性名说明类型默认值
autofocus自动获取焦点booleanfalse
autoSize自动调整高度boolean | { minRows: number, maxRows: number }false
allowSpeech是否开启语音输入booleanfalse
allowFiles是否允许文件上传booleantrue
clearable是否可清空booleanfalse
disabled是否禁用booleanfalse
modelValue绑定值(v-model)string''
defaultValue默认值(非响应式)string''
loading是否加载中booleanfalse
mode输入框类型'single' | 'multiple''single'
maxLength最大输入长度numberInfinity
placeholder输入框占位文本string'请输入内容...'
speech语音识别配置'boolean' | 'SpeechConfig'
showWordLimit是否显示字数统计booleanfalse
stopText停止按钮文字string仅显示图标
submitType提交方式'enter' | 'ctrl+enter' | 'shift+enter''enter'
theme主题样式'light' | 'dark''light'
suggestions输入建议列表string[][]
suggestionPopupWidth输入建议弹窗宽度'number' | 'string'400px
templateData模板数据,用于初始化或 v-model 更新UserItem[][]

Events

事件名说明回调参数
update:modelValue输入值变化时触发(v-model)(value: string)
blur输入框失去焦点时触发(event: FocusEvent)
change输入值改变且失焦时触发(value: string)
focus输入框获得焦点时触发(event: FocusEvent)
input输入值改变时触发(value: string)
submit提交内容时触发(value: string)
clear清空内容时触发()
cancel取消发送(加载状态)时触发()
speech-start语音识别开始时触发()
speech-end语音识别结束时触发(transcript: string)
speech-interim语音识别中间结果时触发(transcript: string)
speech-error语音识别错误时触发(error: Error)
suggestion-select选择输入建议时触发(value: string)

Methods

方法名说明参数返回值
focus使输入框获取焦点-void
blur使输入框失去焦点-void
clear清空输入内容-void
submit手动触发提交事件-void
startSpeech开始语音识别-Promise<void>
stopSpeech停止语音识别-void
activateTemplateFirstField激活模板的第一个输入字段-void

Slots

组件布局结构如下:

+----------------------+
|      header slot     |  <!-- 位于内容区域上方 -->
+----------------------+
| prefix |   content   | actions  <!-- 横向排列 -->
| slot   |    area     | slot
+----------------------+
|footer-left | footer-right|  <!-- 底部左右两侧区域 -->
+----------------------+
插槽名称描述CSS类名默认内容
header头部插槽,位于输入框上方.tiny-sender__header-slot
prefix前缀插槽,位于输入框左侧.tiny-sender__prefix-slot
actions后缀插槽,位于输入框右侧.tiny-sender__actions-slot单行模式下的操作按钮
footer-left底部左侧插槽,保留字数限制.tiny-sender__footer-left字数限制
footer-right底部右侧插槽,保留操作按钮.tiny-sender__footer-right多行模式下的操作按钮
footer底部完全自定义插槽(向后兼容).tiny-sender__footer-slot无 (会覆盖其他底部元素)
decorativeContent装饰性内容插槽,启用后禁止输入.tiny-sender__decorative-content

Types

typescript
interface SpeechConfig {
  lang?: string // 识别语言,默认浏览器语言
  continuous?: boolean // 是否持续识别
  interimResults?: boolean // 是否返回中间结果
  autoReplace?: boolean // 是否自动替换当前输入内容
}