跳转到内容

对话输入框 Sender

Sender 对齐 Ant Design X 的输入框结构与交互:输入区默认在 Enter 时提交,加载态切换为停止操作,并提供头部、前缀、后缀和底部扩展区域。普通文本模式使用 Textarea;结构化词槽模式直接使用 RichTextEditor,选区、输入法、粘贴、组件节点和光标操作不再由 Sender 单独实现。

  • 构建聊天、智能助手或提示词输入区域。
  • 输入框需要发送、停止生成、语音输入或粘贴文件等操作。
  • 需要把参数、标签和可编辑内容组合为结构化词槽。

通过 v-model 绑定内容,按 Enter 或点击发送按钮触发 submit。Shift + Enter 保留为换行。

SenderHeader 放入 header 插槽,可展示引用、附件或上下文信息。展开与收起动画沿用 Ant Design X 的高度和边框过渡。

设置 slot-config 后进入词槽模式。Sender 会把配置转换为 RichTextEditor 的文本和组件节点:inputselecttag 直接使用其内置节点,content 复用输入节点,custom 使用 node-senderCustom 动态插槽。formatResult 只改变最终拼接结果,不改变控件中显示的原始值。词槽模式请从 changesubmitgetValue() 读取结果。

prefixsuffixfooter 都是 Vue 插槽。suffix 插槽会替换默认操作按钮,并提供与默认行为一致的 actions。默认情况下 suffix 位于输入区右侧;设置 suffix-placement="footer" 后,suffix 会移动到 .sd-sender-footer 右侧,footer 插槽只负责左侧内容。

SenderSwitch 用于展示与输入框关联的功能开关。

allow-speech 设为 true 或配置对象后,Sender 使用 getUserMedia + AudioWorklet 采集单声道 Float32 PCM。组件本身不调用浏览器语音识别,也不会把识别文本写入输入框;业务可以通过 speech-startspeech-dataspeech-endspeech-error 把音频交给任意第三方 SDK。

每个 speech-data 都包含可直接传输的 ArrayBuffer、当前 sampleRate、从 0 开始的 sequence 和高精度 timestamp。默认每 4096 个采样点抛出一块数据,可用 bufferSize 调整。

直接连接后端时,在 allow-speech 配置中传入 ws://wss:// 地址即可:

<sd-sender
:allow-speech="{
url: 'wss://api.example.com/asr/stream',
protocols: 'pcm-f32',
bufferSize: 4096,
}"
@speech-transport-message="handleRecognitionResult"
@speech-error="handleSpeechError"
/>

连接建立后,Sender 先发送一条 JSON 元数据:

{ "type": "start", "format": "pcm-f32", "channels": 1, "sampleRate": 48000, "bufferSize": 4096 }

随后连续发送 AudioWorklet 产生的二进制 ArrayBuffer;结束时发送 {"type":"end","reason":"manual"} 并正常关闭连接。后端不需要元数据帧时可设置 sendMetadata: false。服务端返回的流式识别结果通过 speech-transport-message 原样透出。

根据当前 Agent 切换 skillslot-config,并组合 SenderSwitch、自适应高度、加载与停止操作,构成完整的 AI 输入工作流。

通过组件实例调用 insert()focus()clear()getValue()。插入操作支持开头、末尾和当前光标位置。

默认使用 Enter 发送、Shift + Enter 换行;设置 submit-type="shiftEnter" 后两者行为互换。

auto-size 可限制自适应输入区的最小和最大行数。只读状态保留内容查看能力,hover、点击或尝试修改时都会显示 Tooltip;readonly 传入字符串可自定义提示文案。禁用状态同时关闭输入和操作。

剪贴板只包含文件时触发 paste-file,可配合 SenderHeader 展示待发送文件;普通文本粘贴仍写入输入框。

参数名 描述 类型 默认值
v-model 输入内容;词槽模式下不作为结构化内容的状态源 string -
default-value 非受控模式默认内容 string ''
loading 加载中,默认发送按钮切换为停止按钮 boolean false
readonly 是否只读;传入字符串时作为只读提示文案 boolean | string false
disabled 是否禁用 boolean false
submit-type 提交快捷键模式 'enter' | 'shiftEnter' 'enter'
slot-config 结构化词槽配置 SenderSlotConfig[] -
skill 技能标签配置 SenderSkill -
allow-speech AudioWorklet 语音采集、WebSocket 传输或受控录音配置 boolean | SenderSpeechConfig false
auto-size 输入区自适应高度 boolean | { minRows?: number; maxRows?: number } { maxRows: 8 }
placeholder 占位文本 string -
show-actions 是否显示后缀操作区 boolean true
suffix-placement 后缀操作区位置;footer 时位于 footer 右侧 'content' | 'footer' 'content'
components 替换内部输入组件 { input?: Component } -
class-names 语义化节点类名 Partial<Record<SenderSemanticType, string>> -
styles 语义化节点样式 Partial<Record<SenderSemanticType, CSSProperties>> -
事件名 描述 参数
update:model-value 输入内容变化 value: string
change 普通输入或结构化词槽变化 value, event, slotConfig, skill
submit 点击发送或使用提交快捷键 value, slotConfig, skill
cancel 加载态点击停止按钮 -
paste 粘贴内容 event: ClipboardEvent
paste-file 剪贴板仅包含文件时 files: FileList
focus 输入区获取焦点 event: FocusEvent
blur 输入区失去焦点 event: FocusEvent
speech-start 开始采集;受控模式下表示开始意图 SenderSpeechStartEvent
speech-data AudioWorklet 产生一块 PCM 流数据 SenderSpeechDataEvent
speech-end 采集结束并完成资源释放 SenderSpeechEndEvent
speech-error 麦克风、音频上下文、Worklet 或传输失败 SenderSpeechErrorEvent
speech-transport-open WebSocket 连接已建立 { event, socket }
speech-transport-message 收到后端流式消息 { event, socket }
speech-transport-close WebSocket 连接已关闭 { event, socket }
插槽名 描述 参数
header 输入区上方的头部面板 { actions }
prefix 输入区左侧内容 { actions }
suffix 输入区右侧操作区;使用后替换默认操作 { actions }
footer Footer 左侧内容;不再独立控制整个 footer 是否显示 { actions }
skill-title 自定义技能标题 { skill }
skill-close-icon 自定义技能关闭图标 { skill }
slot-key 自定义 custom 词槽 { value, item, disabled, readonly, onChange }

actions 包含 sendclearcancelspeech 以及对应的禁用状态、recordingloading

参数名 描述 类型 默认值
recording 受控录音状态;与 onRecordingChange 同时提供时,Sender 不采集音频 boolean -
onRecordingChange 受控状态回调,或监听内部采集状态 (recording: boolean) => void -
audioConstraints 传给 getUserMedia 的音频约束 MediaTrackConstraints true
bufferSize 每个 speech-data 的 Float32 采样点数量 number 4096
workletUrl 自定义 AudioWorklet 模块地址 string 内置模块
processorName 自定义 Worklet processor 名称 string 'sd-sender-audio-processor'
processorOptions 额外的 Worklet processorOptions Record<string, unknown> -
url 自动流式发送 buffer 的 WebSocket 地址 string -
protocols WebSocket 子协议 string | string[] -
sendMetadata 是否在音频二进制流前后发送 start/end 元数据 boolean true

如果同时传入 recordingonRecordingChange,Sender 保持受控模式兼容:点击按钮只回调期望状态,并抛出 speech-start / speech-end 意图事件,不会申请麦克风。第三方 SDK 可以据此完全接管录音生命周期。

方法名 描述
focus(options?) 聚焦输入区,可指定 startendallslot
blur() 取消焦点
insert(value, position?, replaceCharacters?, preventScroll?) 在开头、结尾或光标处插入文本/词槽
clear() 清空输入;保留传入的 skill 配置
getValue() 返回 { value, slotConfig, skill }
type 关键配置 说明
text value RichTextEditor 文本节点
input keyprops.defaultValueprops.placeholder 内联输入框
select keyprops.optionsprops.defaultValue 内联选择器
tag keyprops.labelprops.value 不可编辑标签
content keyprops.defaultValueprops.placeholder 复用 RichTextEditor 输入节点
custom keycustomRenderslot-key 自定义控件

所有非 text 词槽都需要唯一 key;所有类型都可以通过 formatResult(value) 格式化最终结果。词槽配置是 Sender 的兼容适配层,编辑状态与 DOM 行为以 RichTextEditor 为唯一实现。

参数名 描述 类型 默认值
v-model:open 是否展开 boolean false
title 标题 VNodeChild -
closable 是否显示关闭按钮 boolean true
force-render 关闭后是否保留内容 DOM boolean false

关闭按钮触发 update:openopen-change

参数名 描述 类型 默认值
v-model 是否选中 boolean -
default-value 非受控默认值 boolean false
disabled 是否禁用 boolean false
loading 是否加载中 boolean false

状态变化触发 change(checked)checkeduncheckedicon 和默认插槽可定制内容。