WebSocket原生实现

WebSocket-Vue2

WebSocket-Vue3

前端实现

目录结构

在这里插入图片描述

登录(LoginView.vue)

<template>
  <div class="login">
    <input type="text" placeholder="请输入用户名" v-model="userName"><br>
    <input type="password" placeholder="请输入密码" v-model="passWord"><br>
    <button @click="handleEntryClick">登录</button>
  </div>
</template>
<script>
import {ref, onMounted} from 'vue'
import {useRouter} from 'vue-router'
export default {
  name: 'Login',
  setup () {
    const userName = ref('')
    const passWord = ref('')
    const router = useRouter()
    onMounted(() => {
      console.log(localStorage.getItem('userName'))
      if (!localStorage.getItem('userName')) {
        router.push('/')
        return
      }
    })
    const handleEntryClick = () => {
      const _passWord = passWord.value.trim()
      console.log('userName', userName)
      console.log('passWord', passWord)
      if (_passWord.length < 6) {
        alert('密码不能小于6位')
        return
      }
      localStorage.setItem('userName', userName.value)
      userName.value = ''
      passWord.value = ''
      router.push('/home')
    }



    return {
      userName,
      passWord,
      handleEntryClick
    }
  }
}
</script>

聊天室(HomeView.vue)

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


<script>
import {reactive, onMounted, toRefs} from 'vue'
import {useRouter} from 'vue-router'
import useWebSocket from '@/hooks'
export default {
  name: 'HomeView',
  components: {
  },
  setup() {
    const state = reactive({
      msg: '',
      msgList: []
    })
    let userName = localStorage.getItem('userName')
    const router = useRouter()
    const ws = useWebSocket(handleMessage)
    onMounted (() => {
      if (!userName) {
        router.push('/')
      }
    })
    const handleSendMsg = () => {
       
      if (!state.msg.trim().length) {
        return
      }

      ws.send(JSON.stringify({
         user: userName,
          msg: state.msg,
          dateTime: new Date().getDate()
      }))
    }
    function handleMessage ({data}) {
      console.log('data',JSON.parse(data))
      const msg = JSON.parse(data)
      state.msgList.push(msg)

    }
    return {
      ...toRefs(state),
      handleSendMsg
    }
  }
}
</script>

webscoket封装

import WS_BASE_URL from '../configs'
function useWebSocket (handleMessage) {
  const ws = new WebSocket(WS_BASE_URL)
  const init = () => {
    bindEvent()
  }
  function bindEvent () {
    console.log('绑定事件')
    ws.addEventListener('close', handleClose, false)
    ws.addEventListener('open', handleOpen, false)
    ws.addEventListener('error', handleError, false)
    ws.addEventListener('message', handleMessage, false)
  }
  function handleOpen (e) {
    console.log('handleOpen', e)
  }
  function handleClose (e) {
    console.log('handleClose', e)
  }
  function handleError(e) {
    console.log('handleError', e)
  }
  init()
  return ws
}
export default useWebSocket

效果实现

在这里插入图片描述

GitHub 加速计划 / vu / vue
80
16
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:4 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 6 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 7 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐