Vue+Nodejs+WebSocket实现多人聊天室

news/2024/7/19 12:55:25 标签: vue, nodejs, js, 前端, websocket

码字不易,有帮助的同学希望能关注一下我的微信公众号:Code程序人生,感谢!代码自用自取。

上篇文章已经给大家介绍了使用原生JavaScript+Nodejs+WebSocket实现多人聊天室的内容。

这期的话,我们使用Vue2.x版本同样使用Nodejs+WebSocket继续实现多人聊天室功能。

因为上期已经很详细的介绍了WebSocket的一些重要的事件处理函数,这期的话就不详细介绍了。只是用Vue2.x的版本再做一下,感受一下区别。

首先我们应该使用VueCli新建一个Vue2.x版本的项目。
然后整理一下文件目录,删除无用的内容。
在这里插入图片描述
我们只用到两个视图,分别是HomeLogin
main.js的内容不动。
router文件夹的index.js稍微改一下路由:

import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../views/Login.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/Login',
    name: 'Login',
    component: Login
  },
  {
    path: '/',
    name: 'Home',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "Home" */ '../views/Home.vue')
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

然后我们看一下视图中的Login.vue

<template>
  <div class="about">
    Login
    <input type="text" placeholder="请输入用户名"  v-model="username"/>
    <button @click='handleEnterBtnClick'>进入聊天室</button>
  </div>
</template>

<script>
export default {
  name:'Login',
  data () {
    return {
      username:''
    }
  },
  mounted () {
    const username = localStorage.getItem('username');

    if(username){
      this.$router.push('/');
      return;
    }
  },
  methods: {
    handleEnterBtnClick(){
      const username = this.username.trim();
      console.log(username);
      if(username.length < 6){
        alert('用户名不能小于六位');
        return;
      }

      localStorage.setItem('username',username);
      this.$router.push('/');
    }
  }
}
</script>

这和之前的原生JavaScript版本的entry.html的作用一样。

使用vue原生JavaScript最明显的区别就是不用操作dom了,减少了很多的操作。

Home.vue是聊天室的内容。

<template>
  <div class="home">
    <ul>
      <li v-for="item in msgList" :key="item.id">
        <p>
          <span>{{ item.user }}</span>
          <span>{{ new Date(item.dateTime) }}</span>
        </p>
        <p>消息:{{item.msg}}</p>
      </li>
    </ul>
    <input type="text" placeholder="请输入消息"  v-model="msg"/>
    <button @click="handleSendBtnClick">发送</button>
  </div>
</template>

<script>

const ws = new WebSocket('ws://localhost:8000');


export default {
  name: 'Home',
  data () {
    return {
      msg:'',
      username:'',
      msgList:[]
    }
  },
  mounted () {
    this.username = localStorage.getItem('username');

    if(!this.username){
      this.$router.push('/login');
      return;
    }

    ws.addEventListener('open',this.handleWsOpen.bind(this),false);
    ws.addEventListener('close',this.handleWsClose.bind(this),false);
    ws.addEventListener('error',this.handleWsError.bind(this),false);
    ws.addEventListener('message',this.handleWsMessage.bind(this),false);

  },
  methods: {
    handleSendBtnClick(){
      const msg = this.msg;
      if(!msg.trim().length){
        return;
      }

      ws.send(JSON.stringify({
        id: new Date().getTime(),
        user:this.username,
        dateTime:new Date().getTime(),
        msg:this.msg
      }))
      this.msg = '';  
    },
    handleWsOpen(e){
      console.log('FE:WebSocket open',e);
    },
    handleWsClose(e){
      console.log('FE:WebSocket close',e);
    },
    handleWsError(e){
      console.log('FE:WebSocket error',e);
    },
    handleWsMessage(e){
      // console.log(e);
      // console.log('FE:WebSocket message',e.data);
      const msg = JSON.parse(e.data);
      console.log(msg);
      this.msgList.push(msg);
    }
  }

}
</script>

和之前的原生JavaScript版本没有太大的区别,最大的感受就是不用再操作dom了。

后端的话,我们就直接在根目录新建一个server文件夹。

npm i ws -s

index.js内容:

const ws = require('ws');

const server = new ws.Server({
    port:8000
})

server.on('open',handleOpen);
server.on('close',handleClose);
server.on('error',handleError);
server.on('connection',handleConnection);

function handleOpen(){
    console.log('BE:WebSocket open');
}
function handleClose(){
    console.log('BE:WebSocket close');
}
function handleError(){
    console.log('BE:WebSocket error');
}
function handleConnection(e){
    console.log('BE:WebSocket connection');
    e.on('message',handleMessage);
}
function handleMessage(msg){
    console.log(msg);
    console.log(server.clients);
    server.clients.forEach((c)=> {
        c.send(msg);
    })
}

因为大部分的事件处理函数都和原生的JavaScript版本一模一样,所以就不做过多的解释了。大家可以直接复制代码体验。

项目运行的结果和原生JavaScript一样。
在这里插入图片描述

完整的源代码文件关注我的公众号Code程序人生,回复关键字聊天室


有微信小程序课设、毕设需求联系个人QQ:505417246

关注下面微信公众号,可以领取微信小程序、Vue、TypeScript、前端、uni-app、全栈、Nodejs、Python等实战学习资料
最新最全的前端知识总结和项目源码都会第一时间发布到微信公众号,请大家多多关注,谢谢!

在这里插入图片描述


http://www.niftyadmin.cn/n/1576552.html

相关文章

如何开启MYSQL的严格模式

1.可以通过执行SQL语句来开启&#xff0c;但是只对当前连接有效&#xff0c;下面是SQL语句&#xff1a;set sql_mode"STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";2.通过修改MySQL的配置文件&#xff0c;在配置文件中查找sql-mode&#xff0c;…

前端面试题之---树形数据结构化

码字不易&#xff0c;有帮助的同学希望能关注一下我的微信公众号&#xff1a;Code程序人生&#xff0c;感谢&#xff01;代码自用自取。 话不多说&#xff0c;直接上题。 const data [{id:2,pid:0,path:/course,name:Course,title:课程管理},{id:3,name:CourseOperate,path:o…

使用 Electron 构建桌面应用(拖动控制篇)

使用 Electron 构建桌面应用&#xff08;拖动控制篇&#xff09; 当窗口被定义了大小&#xff0c;我们也就是在自定义这个窗口&#xff0c;使得它不可拉伸没有框架&#xff0c;让它看起来就像一个真正的声效器浮在桌面上。 现在问题来了 – 要如何移动或者关闭一个没有标题栏的…

揭秘 Vue.js 九个性能优化技巧

这篇文章主要参考了 Vue.js 核心成员 Guillaume Chau 在 19 年美国的 Vue conf 分享的主题&#xff1a;9 Performance secrets revealed&#xff0c;分享中提到了九个 Vue.js 性能优化的技巧。 我看完他的分享 PPT后&#xff0c;也阅读了相关的项目源码&#xff0c;在深入了解它…

前端面试100问(1)

从今天开始&#xff0c;给大家带来一个系列&#xff0c;关于前端面试题的100问&#xff0c;基本涵盖所有前端技术栈&#xff0c;大量大厂真题&#xff0c;各个级别的都有&#xff0c;题目来自GitHub。 今天的问题是&#xff1a; 写React/Vue项目时为什么要在列表组件中写key&a…

前端面试100问(2)

码字不易&#xff0c;有帮助的同学希望能关注一下我的微信公众号&#xff1a;Code程序人生&#xff0c;感谢&#xff01;代码自用自取。 题目&#xff1a; [‘1’, ‘2’, ‘3’].map(parseInt) what & why ? 第一眼看到这个题目的时候&#xff0c;脑海跳出的答案是 [1, …

SSH整合简单例子

说明&#xff1a;简单SSH整合&#xff0c;struts版本2.3.32&#xff0c;spring版本3.2.9&#xff0c;hibernate版本3.6.10 一、开发步骤 1 引jar包&#xff0c;创建用户library。使用的包和之前博文相同&#xff0c;可以参考spring和hibernate整合&#xff0c;事务管理&#xf…

前端面试100问(3)

码字不易&#xff0c;有帮助的同学希望能关注一下我的微信公众号&#xff1a;Code程序人生&#xff0c;感谢&#xff01;代码自用自取。 题目&#xff1a; 什么是防抖和节流&#xff1f;有什么区别&#xff1f;如何实现&#xff1f; 防抖 触发高频事件后n秒内函数只会执行一次…