vue.js+socket.io+express+mongodb打造在线聊天[二]

时间:2024-01-23 09:24:02

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
            }
        }
    }
})