MessageInput
概述
MessageInput 是一个功能完整的消息输入组件,提供了文本编辑、表情选择、文件附件、发送按钮等核心聊天输入功能。该组件支持丰富的自定义选项,包括输入行为配置、工具栏定制、组件替换和插槽扩展,能够满足不同聊天场景的个性化需求。
Props 属性
字段 | 类型 | 默认值 | 描述 |
boolean | true | 是否自动聚焦到输入框 | |
boolean | false | 是否禁用输入组件 | |
boolean | false | 是否隐藏发送按钮 | |
string | '' | 输入框占位符文本 | |
string | undefined | 根容器自定义 CSS 类名 | |
React.CSSProperties | undefined | 根容器自定义内联样式 | |
'collapsed' | 'expanded' | 'collapsed' | 附件选择器显示模式 | |
MessageInputActions | ['EmojiPicker', 'AttachmentPicker'] | 工具栏操作按钮配置 | |
MessageInputSlots | undefined | 插槽配置对象 | |
JSX.Element | undefined | 自定义文本编辑器组件 | |
JSX.Element | undefined | 自定义表情选择器组件 | |
JSX.Element | undefined | 自定义附件选择器组件 | |
JSX.Element | undefined | 自定义文件选择器组件 | |
JSX.Element | undefined | 自定义图片选择器组件 | |
JSX.Element | undefined | 自定义视频选择器组件 |
属性详解
autoFocus
参数类型:
boolean
autoFocus 用于设置是否在组件挂载时自动聚焦到输入框,默认值为
true
。disabled
参数类型:
boolean
disabled 用于设置是否禁用整个输入组件,包括文本输入和所有操作按钮,默认值为
false
。hideSendButton
参数类型:
boolean
hideSendButton 用于设置是否隐藏发送按钮,适用于需要自定义发送触发方式的场景,默认值为
false
。placeholder
参数类型:
string
placeholder 用于设置输入框的占位符文本,默认值为空字符串。
className
参数类型:
string
className 用于设置根容器自定义 CSS 类名,默认值为
undefined
。style
参数类型:
React.CSSProperties
style 用于设置根容器自定义内联样式,默认值为
undefined
。attachmentPickerMode
参数类型:
'collapsed' | 'expanded'
attachmentPickerMode 用于设置附件选择器的显示模式,默认值为
'collapsed'
。collapsed
: 收起模式,点击后展开选项expanded
: 展开模式,直接显示所有选项说明:
默认的 AttachmentPicker 意为附件选择器,包括文件选择、图片选择和视频选择。
1. 当 attachmentPickerMode 为 "collapsed" 时,点击附件选择器会弹出一个 popup 菜单展示文件选择、图片选择、视频选择。
2. 当 attachmentPickerMode 为 "expanded" 时,附件选择器会默认展开,平铺展示文件选择、图片选择、视频选择。
actions
参数类型:
MessageInputActions
actions 用于配置工具栏中显示的操作按钮,默认值为
['EmojiPicker', 'AttachmentPicker']
。type BuiltInAction =| 'EmojiPicker'| 'ImagePicker'| 'FilePicker'| 'VideoPicker'| 'AttachmentPicker';type CustomAction = {key: string;label?: string | undefined;component?: React.ComponentType<any> | undefined;className?: string | undefined;style?: React.CSSProperties | undefined;iconSize?: number | undefined;};type MessageInputActions = Array<BuiltInAction | CustomAction>;
示例1: 自定义工具栏按钮顺序
import { Chat, MessageInput } from '@tencentcloud/chat-uikit-react';function ChatWithCustomActions() {// 自定义按钮顺序:文件、图片、视频、表情const customActions = ['FilePicker', 'ImagePicker', 'VideoPicker', 'EmojiPicker'];return (<Chat><MessageInput actions={customActions} /></Chat>);}
效果图如下图所示:

示例2: 添加自定义操作按钮 - 客服系统快捷回复
import { Chat, MessageInput, useMessageInputState } from '@tencentcloud/chat-uikit-react';// 快捷回复组件function QuickReplyPicker() {const { setContent } = useMessageInputState();const quickReplies = ['您好,很高兴为您服务!','请稍等,我来为您查询...','感谢您的咨询,还有其他问题吗?','问题已为您解决,祝您生活愉快!'];const handleQuickReply = (text: string) => {setContent(text);};return (<div style={{ position: 'relative' }}><button title="快捷回复">⚡</button><div style={{position: 'absolute',bottom: '100%',left: 0,background: 'white',border: '1px solid #ccc',borderRadius: '4px',padding: '8px',minWidth: '200px'}}>{quickReplies.map((reply, index) => (<divkey={index}onClick={() => handleQuickReply(reply)}style={{padding: '4px 8px',cursor: 'pointer',borderRadius: '2px'}}>{reply}</div>))}</div></div>);}function CustomerServiceChat() {const actions = [{key: 'quickReply',label: '快捷回复',component: QuickReplyPicker},'EmojiPicker','FilePicker'];return (<Chat><MessageInput actions={actions} /></Chat>);}
效果图如下图所示:

slots
参数类型:
MessageInputSlots
slots 用于在输入组件的特定位置插入自定义内容,默认值为
undefined
。interface MessageInputSlots {headerToolbar?: () => React.ReactNode;footerToolbar?: () => React.ReactNode;leftInline?: () => React.ReactNode;rightInline?: () => React.ReactNode;inputPrefix?: () => React.ReactNode;inputSuffix?: () => React.ReactNode;}

示例1: 添加消息统计显示
import { Chat, MessageInput, useMessageInputState } from '@tencentcloud/chat-uikit-react';function ChatWithMessageStats() {const { inputRawValue } = useMessageInputState();// 头部工具栏:显示字符统计const HeaderToolbar = () => !inputRawValue? null: (<div style={{padding: '4px 12px',fontSize: '12px',color: '#666',borderBottom: '1px solid #eee',}}>Character count:{' '}{inputRawValue?.reduce((acc, item) => acc + (item.type === 'text' ? item.content.length : 1), 0) || 0}/500</div>);// 底部工具栏:显示发送提示const FooterToolbar = () => (<div style={{padding: '4px 12px',fontSize: '12px',color: '#999',textAlign: 'right'}}>Press Ctrl+Enter to enter a new line</div>);return (<Chat><MessageInputslots={{headerToolbar: HeaderToolbar,footerToolbar: FooterToolbar}}/></Chat>);}
效果图如下图所示:

示例2: 输入框前后缀功能
import { Chat, MessageInput } from '@tencentcloud/chat-uikit-react';function ChatWithInputPrefixSuffix() {// 输入框前缀:@提醒功能const InputPrefix = () => (<buttonstyle={{border: 'none',background: 'transparent',color: '#1890ff',cursor: 'pointer'}}onClick={() => {// 触发@用户选择console.log('打开@用户选择');}}>@</button>);// 输入框后缀:语音输入const InputSuffix = () => (<buttonstyle={{border: 'none',background: 'transparent',cursor: 'pointer'}}onClick={() => {// 开始语音输入console.log('开始语音输入');}}>🎤</button>);return (<Chat><MessageInputslots={{inputPrefix: InputPrefix,inputSuffix: InputSuffix}}/></Chat>);}
效果图如下图所示:

示例3: 完全自定义左右侧工具栏
import { Chat, MessageInput } from '@tencentcloud/chat-uikit-react';function ChatWithCustomToolbars() {// 左侧工具栏:仅保留表情和图片const LeftInline = () => (<div style={{ display: 'flex', gap: '8px' }}><button>😊</button><button>📷</button></div>);// 右侧工具栏:自定义发送区域const RightInline = () => (<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}><span style={{ fontSize: '12px', color: '#666' }}>Enter</span><buttonstyle={{padding: '6px 12px',background: '#1890ff',color: 'white',border: 'none',borderRadius: '4px',cursor: 'pointer'}}>发送</button></div>);return (<Chat><MessageInputslots={{leftInline: LeftInline,rightInline: RightInline}}/></Chat>);}
效果图如下图所示:

TextEditor
参数类型:
JSX.Element
TextEditor 用于替换默认的文本编辑器组件,默认值为
undefined
。示例: 集成富文本编辑器
import { Chat, MessageInput, useMessageInputState } from '@tencentcloud/chat-uikit-react';// 自定义富文本编辑器function RichTextEditor() {const { sendMessage } = useMessageInputState();const [inputValue, setInputValue] = useState('');const handleContentChange = (content: string) => {setInputValue(content);};const handleKeyDown = (e: React.KeyboardEvent) => {// Enter 发送消息if (e.key === 'Enter') {// 触发发送逻辑e.preventDefault();sendMessage(inputValue);// 清空 editable div 的输入内容const editableDiv = document.querySelector('.editable-div');if (editableDiv) {editableDiv.textContent = '';}}};return (<div style={{flex: 1,border: '1px solid #d9d9d9',borderRadius: '6px',padding: '8px 12px',minHeight: '32px',maxHeight: '120px',overflow: 'auto',}}><divcontentEditableclassName="editable-div"style={{outline: 'none',minHeight: '20px',lineHeight: '20px',}}onInput={(e) => {handleContentChange(e.currentTarget.textContent || '');}}onKeyDown={handleKeyDown}/></div>);}function ChatWithRichTextEditor() {return (<Chat><MessageInput TextEditor={<RichTextEditor />} /></Chat>);}
效果图如下图所示:

EmojiPicker
参数类型:
JSX.Element
EmojiPicker 用于替换默认的表情选择器组件,默认值为
undefined
。示例: 自定义表情面板
import { Chat, MessageInput, useMessageInputState } from '@tencentcloud/chat-uikit-react';// 自定义表情选择器function CustomEmojiPicker() {const { insertContent } = useMessageInputState();const emojiCategories = {common: ['😀', '😂', '🥰', '😍', '🤔', '😭', '😡', '👍'],hands: ['👋', '🤝', '👏', '🙏', '✌️', '🤞', '🤟', '👌'],animals: ['🐶', '🐱', '🐭', '🐹', '🐰', '🦊', '🐻', '🐼'],};const [activeCategory, setActiveCategory] = useState('common');const [showPicker, setShowPicker] = useState(false);const insertEmoji = (emoji: string) => {insertContent(emoji);setShowPicker(false);};return (<div style={{ position: 'relative' }}><buttononClick={() => setShowPicker(!showPicker)}style={{ border: 'none', background: 'transparent', cursor: 'pointer' }}>😊</button>{showPicker && (<div style={{position: 'absolute',bottom: '100%',left: 0,background: 'white',border: '1px solid #ccc',borderRadius: '8px',padding: '12px',width: '280px',boxShadow: '0 4px 12px rgba(0,0,0,0.1)',}}>{/* 分类标签 */}<div style={{ display: 'flex', marginBottom: '8px' }}>{Object.keys(emojiCategories).map(category => (<buttonkey={category}onClick={() => setActiveCategory(category)}style={{padding: '4px 8px',border: 'none',background: activeCategory === category ? '#1890ff' : 'transparent',color: activeCategory === category ? 'white' : '#666',borderRadius: '4px',cursor: 'pointer',fontSize: '12px',}}>{category}</button>))}</div>{/* 表情网格 */}<div style={{display: 'grid',gridTemplateColumns: 'repeat(8, 1fr)',gap: '4px',}}>{emojiCategories[activeCategory].map(emoji => (<buttonkey={emoji}onClick={() => insertEmoji(emoji)}style={{border: 'none',background: 'transparent',fontSize: '20px',cursor: 'pointer',padding: '4px',borderRadius: '4px',}}>{emoji}</button>))}</div></div>)}</div>);}function ChatWithCustomEmoji() {return (<Chat><MessageInput EmojiPicker={<CustomEmojiPicker />} /></Chat>);}
效果图如下图所示:

AttachmentPicker
参数类型:
JSX.Element
AttachmentPicker 用于替换默认的附件选择器组件,默认值为
undefined
。示例: 云存储集成的附件选择器
import { Chat, MessageInput } from '@tencentcloud/chat-uikit-react';// 集成云存储的附件选择器function CloudAttachmentPicker() {const [showPicker, setShowPicker] = useState(false);const attachmentTypes = [{ key: 'local', label: '本地文件', icon: '📁' },{ key: 'cloud', label: '云端文件', icon: '☁️' },{ key: 'recent', label: '最近文件', icon: '🕒' },{ key: 'screenshot', label: '截图', icon: '📷' }];const handleAttachmentSelect = async (type: string) => {switch (type) {case 'local':// 打开本地文件选择const input = document.createElement('input');input.type = 'file';input.multiple = true;input.onchange = (e) => {const files = (e.target as HTMLInputElement).files;console.log('选择的本地文件:', files);};input.click();break;case 'cloud':// 打开云端文件选择console.log('打开云端文件选择');break;case 'recent':// 显示最近文件console.log('显示最近文件');break;case 'screenshot':// 开始截图console.log('开始截图');break;}setShowPicker(false);};return (<div style={{ position: 'relative' }}><buttononClick={() => setShowPicker(!showPicker)}style={{ border: 'none', background: 'transparent', cursor: 'pointer' }}>📎</button>{showPicker && (<div style={{position: 'absolute',bottom: '100%',left: 0,background: 'white',border: '1px solid #ccc',borderRadius: '8px',padding: '8px',minWidth: '160px',boxShadow: '0 4px 12px rgba(0,0,0,0.1)'}}>{attachmentTypes.map(type => (<divkey={type.key}onClick={() => handleAttachmentSelect(type.key)}style={{display: 'flex',alignItems: 'center',gap: '8px',padding: '8px 12px',cursor: 'pointer',borderRadius: '4px',fontSize: '14px'}}><span>{type.icon}</span><span>{type.label}</span></div>))}</div>)}</div>);}function ChatWithCloudAttachment() {return (<Chat><MessageInput AttachmentPicker={<CloudAttachmentPicker />} /></Chat>);}
效果图如下图所示:

总结
MessageInput 组件提供了完整的消息输入功能和丰富的自定义选项。通过合理配置 Props 和使用插槽系统,您可以创建出符合特定业务需求的输入界面。建议根据实际使用场景选择合适的自定义方案,并注意保持良好的用户体验和性能表现。