vue.js+socket.io+express+mongodb打造在线聊天[二]
在线地址观看
http://www.chenleiming.com/vuechat
github地址
https://github.com/clm960227/...
有喜欢的小哥哥,小姐姐请反手来个star,谢谢!有issue的欢迎提出
介绍
本项目基于vue.js+socket.io+express+mongodb实现的聊天效果, 界面以及功能参考QQ,微信
技术栈
- 前端: vue,vue-router,vuex,axios
- 构建: webpack,vue-cli
- 后端: express,multer(上传图片),cors(跨域处理), superagent(调用机器人接口),mongoose(操作数据库)
- 通讯: socket.io
- 数据库: mongodb
- css预处理器: sass
功能列表
- 用户注册
- 用户登录
- 群聊
- 群聊中@小美 和机器人聊天 (注意@小美和消息中间要有空格)
- 机器人聊天
- 留言板
- 更换主题颜色
- 进出聊天群提醒
功能展示
- 登录与注册
- 群聊
- 群聊中与机器人聊天
- 机器人聊天
- 留言板
- 更换主题
好啦~功能差不多就这些啦,这次添加了进出群提醒,主题颜色更换还有布局的一些调整。废话不多说啦,接下来该介绍介绍核心部分,以免被各位小哥哥,小姐姐打。
前端聊天代码
const infoObj = { status: \'userstate\', nickname: this.getUserinfo.nickname, roomId: this.roomId } this.socket.emit(\'join-room\', infoObj) this.socket.on(\'join-room\', (joinInfo) => { this.MsgList.push(joinInfo) this.$nextTick(() => { this.msgDOM.scrollTop = this.msgDOM.scrollHeight }) }) // 聊天 this.socket.on(\'chat-msg\', (msg) => { console.log(msg) this.MsgList.push(msg) this.$nextTick(() => { this.msgDOM.scrollTop = this.msgDOM.scrollHeight }) }) // 离开房间 this.socket.on(\'leave-room\', (leaveInfo) => { this.MsgList.push(leaveInfo) this.$nextTick(() => { this.msgDOM.scrollTop = this.msgDOM.scrollHeight }) })
后端聊天代码
io.on(\'connection\', (socket) => { // 进入房间 socket.on(\'join-room\', (info) => { // 添加到房间 socket.join(info.roomId) const joinInfo = { status: info.status, text: info.nickname + \'加入了群聊\' } socket.to(info.roomId).broadcast.emit(\'join-room\', joinInfo) }) // 群聊天 socket.on(\'chat-msg\', (msg) => { saveChatMsg(msg, () => { io.to(msg.roomId).emit(\'chat-msg\', msg) // 分割聊天消息,判断是否与机器人聊天 const msgArr = msg.text.split(\' \') const robotParam = { userId: msg.userId, roomId: msg.roomId || null, timeStamp: msg.timeStamp + 1 || null, text: msgArr[1] } if (msgArr[0] === \'@小美\') { getRobotMsg(robotParam, (robotmsg) => { saveChatMsg(robotmsg) io.to(msg.roomId).emit(\'chat-msg\', robotmsg) }) } }) }) // 机器人聊天 socket.on(\'robot-msg\', (msg) => { const robotParam = { userId: msg.userId, timeStamp: msg.timeStamp, text: msg.text } getRobotMsg(robotParam, (robotmsg) => { socket.emit(\'robot-msg\', robotmsg) }) }) // 离开房间 socket.on(\'leave-room\', (info) => { socket.leave(info.roomId) const leaveInfo = { status: info.status, text: info.nickname + \'离开了群聊\' } socket.to(info.roomId).broadcast.emit(\'leave-room\', leaveInfo) }) })
vuex
export default new Vuex.Store({ state: { // 主题颜色 themeColor: \'\', // 存放用户信息 userInfo: { userId: \'\', nickname: \'\', headPic: \'\' }, // 机器人信息 robot: { Info: { userId: \'robot\', nickname: \'小美\', headPic: \'/static/img/robot-headpic.jpg\' }, // 机器人打招呼 greetMsg: \'hi~ 我是机器人小美,有什么可以帮您的嘛?\' } }, getters: { // 获取主题颜色 getThemeColor: state => { return state.themeColor }, // 获取登录用户信息 getUserinfo: state => { return state.userInfo }, // 获取机器人信息 getRobotinfo: state => { return state.robot.Info }, // 获取机器人欢迎语 getRobotGreetMsg: state => { return state.robot.greetMsg } }, mutations: { // 设置用户信息 setUserinfo(state, userInfo) { state.userInfo.userId = userInfo.userId state.userInfo.nickname = userInfo.nickname state.userInfo.headPic = userInfo.headPic }, // 设置聊天记录 setHistoryMsg(state, msgList) { state.msgInfo = msgList }, // 设置主题颜色 setThemeColor(state, color) { state.themeColor = color } }, actions: { // 注册用户 async register({commite}, data) { const res = await url.register(data) if (res.data.state === 0) { return { status: \'fail\', data: res.data.data } } return { status: \'success\', data: res.data.data } }, // 登录用户 async login({commite}, data) { const res = await url.login(data) if (res.data.state === 0) { return { status: \'fail\', data: res.data.data } } return { status: \'success\', data: res.data.data } }, // 上传图片 async upload({commite}, data) { await url.upload(data) }, // 获取聊天记录 async getHistoryChatMsg({commite}, data) { const res = await url.gethistorychatmsg(data) return { status: \'success\', data: res.data.data.msgList } }, // 保存留言 async saveLeaveMsg({commite}, data) { const res = await url.saveleavemsg(data) return { status: res.data.data.stateText } }, // 获取留言数据 async getLeaveMsg({commite}) { const res = await url.getleavemsg() return { status: res.data.data.stateText, data: res.data.data.leaveMsg } } } })