效果图:
安装库
用到了antd design和github上的一个库:react-chat-element
(1)antd design:
安装:yarn add antd
修改 src/App.css,在文件顶部引入 antd/dist/antd.css
@import '~antd/dist/antd.css';
即可使用antd的组件
(2)react-chat-element:
github网址为:Detaysoft/react-chat-elements
安装:npm install react-chat-elements --save
即可
代码和基本说明
import React, {createRef} from "react";
import {ChatList, MessageList} from 'react-chat-elements'
import 'react-chat-elements/dist/main.css';
import {Button, Row, Col, Divider, Input} from "antd";const {TextArea} = Input;class ChatWidget extends React.Component {constructor(props) {super(props);this.state = {user: null,msgDataList: [],sendMsg: "",}this.clickButton = this.clickButton.bind(this);this.messagesEnd = createRef();}componentDidMount() {let list = [];for (let i = 0; i < 10; ++i)list.push({position: 'left',type: 'text',text: 'hello' + i,date: new Date(),});this.setState({msgDataList: list});this.setState({user: this.props.user});}componentWillReceiveProps(nextProps, nextContext) {this.setState({user: nextProps.user});}clickButton() {let list = this.state.msgDataList;list.push({position: 'right',type: 'text',text: this.state.sendMsg,date: new Date(),})this.setState({msgDataList: list});this.setState({sendMsg: ""});}componentDidUpdate(prevProps, prevState, snapshot) {this.messagesEnd.scrollTop = this.messagesEnd.scrollHeight;}render() {return (<Col style={{width: 700,height: 600,display: 'inline-block',borderRight: "3px solid",borderTop: "3px solid",borderBottom: "3px solid",}}><Row><Col style={{width: 700,height: 40,textAlign: "center",verticalAlign: "middle",fontSize: 20}}>{this.state.user == null ? "" : this.state.user.title}</Col></Row><Row><div style={{width: 700,height: 420,textAlign: "center",verticalAlign: "middle",fontSize: 20,overflow: "auto",backgroundColor: "\t#C0C0C0"}}ref={(el) => {this.messagesEnd = el;}}><MessageListclassName='message-list'dataSource={this.state.msgDataList}/></div></Row><Row><Col style={{width: 700,textAlign: "center",verticalAlign: "middle",fontSize: 20}}><TextArea rows={4} onChange={e => {this.setState({sendMsg: e.target.value});}}ref={el => (this.inputRef = el)}value={this.state.sendMsg}/><Button type="primary" onClick={this.clickButton}>发送</Button></Col></Row></Col>);}
}class PrivateChatView extends React.Component {constructor(props) {super(props);this.state = {userList: [],clickUser: null,}}componentDidMount() {let list = [];for (let i = 0; i < 14; ++i)list.push({avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',alt: 'Reactjs',title: '用户' + i,subtitle: 'What are you doing?',date: new Date(),unread: Math.floor(Math.random() * 10),});this.setState({userList: list});this.setState({clickUser: list[0]});}render() {return (<div><Divider orientation="left" style={{color: '#333', fontWeight: 'normal'}}>私信列表</Divider><Row><Col style={{width: 400,height: 600,display: 'inline-block',border: "3px solid",overflow:"auto"}}><ChatListclassName='chat-list'onClick={e => this.setState({clickUser: e})}dataSource={this.state.userList}/></Col>{this.state.userList.length == 0 ? <div>无私信</div> : <ChatWidget user={this.state.clickUser}/>}</Row></div>);}
}export default PrivateChatView;
ChatWidget是右边的对话窗口,PrivateChatView是整个聊天组件(包括了聊天列表和ChatWidget)。
PrivateChatView中的userList表示聊天列表的数组。如果想要改变外表(比如未读什么的),详细可以见react-chat-element中对于chatList的描述。PrivateChatView会传一个user参数给ChatWidget,表示是哪一个用户被点击。
ChatWidget接受PrivateChatView传过来的user参数。msgDataList表示聊天记录数组,通过设置数组元素的position是‘right’还是‘left’来决定是消息气泡显示在左边还是右边。
一些问题:
我设置的PrivateChatView里面的聊天列表和ChatWidget用的是display:inline-block,如果将浏览器缩小显示,聊天列表和ChatWidget就会变成上下显示。