Vue + ElementUI + Vue-socket + nodejs实现简单聊天室
前端

我是直接用的vue-cli 新建了一个vue项目,版本选择vue 2.x。一开始我选的是3.x,发现3.x的版本在使用Vue-socket的时候会报错,Github上说这确实存在不兼容的问题,并且vue3.x兼容Elementui感觉也不是很好。

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router/index.js'
import VueSocketio from 'vue-socket.io'; 
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.config.productionTip = false

Vue.use(ElementUI);

Vue.use(new VueSocketio({
    debug: true,
    connection: 'http://localhost:4000', //options object is Optional
  })
);
new Vue({
  render: h => h(App),
  router,
}).$mount('#app')

这里主要就做了三件事:

  • 引入了elementui
  • 配置了vue-socket
  • 使用了路由模块

聊天框组件

/vue2 chatroom/chatroon2/src/pages/chat/index.vue

最后实现的聊天框长这个样子(做的比较简单)
聊天框图片
样式页面结构就不展开赘述了,大家可以去文末我的Github仓库链接拉下代码看下,最关键的就是和vue-socket相关的接受/发送消息的代码:

  sockets: {
        connect: function () {
            console.log('socket connected')
        },
        message: function (data) {
            console.log(data)
            // this.msgList.push(`${data.name}说:${data.msg}`)
            this.msgList.push({
                name: data.name === this.userName ? '我' : data.name,
                msg: data.msg,
                isSelf: data.name === this.userName
            })
        }
    },

这里定义的是接受后台推送的消息的时候的处理方法。

methods: {
        sendMsg: function () {
            // $socket is socket.io-client instance
            const data = {
              name: this.userName,
              msg: this.msg
            }
            this.$socket.emit('message', data)
            this.msg = '';
        }
    }

sendMsg定义了点击发送按钮之后的动作,即把聊天框里的内容和当前用户姓名发送给后台。

this.$socket.emit('message', data)

socket通信前后端发送数据均用emit方法,第一个参数指定接收方的处理函数(比方说这里指定后端的socket.on(‘message’)处理)第二个参数为携带的数据对象。

后端

/vue2 chatroom/server/socket.js

var app = require('express')();
var http=require('http').Server(app);
var io=require('socket.io')(http, {
    allowEIO3: true,
    cors: {
      origin: "http://192.168.199.239:8080",
      methods: ["GET", "POST"],
      // allowedHeaders: ["my-custom-header"],
      credentials: true
    }
  });

// app.get('/socket/client/index.html',function (req,res) {
//     res.send('<h1>welcome</h1>');
// })
//在线用户




var onlineUser={};
var onlineCount=0;

io.on('connection',function (socket) {
    console.log('新用户登录');

    //监听新用户加入
    socket.on('login',function (obj) {
        socket.name=obj.userid;
        //检查用户在线列表
        if(!onlineUser.hasOwnProperty(obj.userid)){
            onlineUser[obj.userid]=obj.username;
            //在线人数+1
            onlineCount++;
        }
        //广播消息
        io.emit('login',{onlineUser:onlineUser,onlineCount:onlineCount,user:obj});
        console.log(obj.username+"加入了聊天室");
    })
    //监听用户退出
    socket.on('disconnect',function () {
        //将退出用户在在线列表删除
        if(onlineUser.hasOwnProperty(socket.name)){
            //退出用户信息
            var obj={userid:socket.name, username:onlineUser[socket.name]};
            //删除
            delete onlineUser[socket.name];
            //在线人数-1
            onlineCount--;
            //广播消息
            io.emit('logout',{onlineUser:onlineUser,onlineCount:onlineCount,user:obj});
            console.log(obj.username+"退出了聊天室");
        }
    })

    //监听用户发布聊天内容
    socket.on('message', function(obj){
        //向所有客户端广播发布的消息
        io.emit('message', obj);
        console.log(obj.name+'说:'+obj.msg);
    });
})
http.listen(4000, function(){
    console.log('listening on *:4000');
});

前面就是先定义好允许跨域的配置,后面定义一系列的监听方法(监听进入、接受消息然后发送给各个客户端)。

为了可以设置自己名字,我写了一个用于设置名字的界面,比较简单,不再赘述。

github链接

Logo

前往低代码交流专区

更多推荐