vue基于websocket实现智能聊天及吸附动画效果

目录
  • 前言:
  • 1.效果如下:
  • 2.主要功能:
    • 2.1.基于websocket实现聊天功能,封装了一个socket.js文件
    • 2.2使用Jwchat插件实现类似QQ、微信电脑端的功能
    • 2.3动画效果(如关闭打开时动画、吸附效果及其他效果)
  • 3.实现步骤:
    • 3.1.实现websocket聊天功能
    • 3.2.在页面中的使用方法:
    • 关闭连接
    • 发送给后端的方法
  • 4.使用Jwchat插件实现类似QQ、微信电脑端的功能
    • 4.1步骤
  • 5.动画效果

前言:

发现这篇文章写的有点多,我总结一下整体思路:

首先这个功能市面上挺多的,我是参考了几家公司的功能实现,发现他们的整体功能实现和下面我的截图类似。

首先核心功能是基于websocket实现用户输入文字服务器根据用户输入返回数据渲染在页面上,而这个功能我不推荐直接使用原生,而是使用封装好的,就像文章里封装的socket.js,这个文件很简单就对外提供三个方法,一个是和后端通信连接,再一个是接收后端的数据,最后一个是发送数据给后端。

其次,我们需要一个聊天框,我使用的Jwchat插件,优点是功能比较全类似QQ聊天,使用方法也很简单,但是话说回来,这个插件的很多样式需要修改,尤其对于要做页面适配的项目,所以这个插件不是特别推荐,还有一个点就是他没有关闭按钮,做的比较粗糙,我是通过在生命周期中使用原生JS添加的关闭图标,然后再通过watch动态的选择要不要创建删除按钮。

最后说一下动画,其实就是一个聊天框,一个小框,通过点击使v-show绑定的变量来实现切换效果。这个吸附效果是我用CSS动画将原本的一个长方形框框翻转180度后在平移模拟吸附效果,其实正儿八经做的话需要计算页面宽度和元素位置计算出一个比例然后再设置一个动画效果,这个GitHub上还是有挺多的,注意的是很多实现都是移动端的,PC端用不了,是个坑。再一个动画就是打开关闭时的效果,使用的是elementUI自带的动画效果。

1.效果如下:

2.主要功能:

2.1.基于websocket实现聊天功能,封装了一个socket.js文件

2.2使用Jwchat插件实现类似QQ、微信电脑端的功能

(其实并不是很好用,但考虑到后续可能会使用其功能就先用了)

2.3动画效果(如关闭打开时动画、吸附效果及其他效果)

3.实现步骤:

3.1.实现websocket聊天功能

首先封装了一个socket.js文件;需要主要的是将socket.js中URL修改成自己的

封装的websocke暴露三个接口

  • sendSock用于发送数据,发给后端
  • createWebSocket用于创建连接、接收数据并进行处理
  • closeSock 用于关闭连接

3.2.在页面中的使用方法:

第一步:导入文件

import { sendSock, createWebSocket, closeSock } from "@/api/socket";

第二步:初始化时建立websocket连接

created() {
    this.init();
    ......
  },
  methods: {
    init() {
      createWebSocket(this.global_callback);
      ......
    },

    // websocket的回调函数,msg表示收到的消息
    global_callback(msg) {
      console.log("收到服务器信息:" + msg);
    },
  },

关闭连接

closeSock();

发送给后端的方法

sendSock(xxx)
var websock = null;
var global_callback = null;
var serverPort = "80"; // webSocket连接端口
var wsuri = "ws://" + window.location.hostname + ":" + serverPort;
function createWebSocket(callback) {
  if (websock == null || typeof websock !== WebSocket) {
    initWebSocket(callback);
  }
}
function initWebSocket(callback) {
  global_callback = callback;
  // 初始化websocket
  websock = new WebSocket(wsuri);
  websock.onmessage = function (e) {
    websocketonmessage(e);
  };
  websock.onclose = function (e) {
    websocketclose(e);
  };
  websock.onopen = function () {
    websocketOpen();
  };
  // 连接发生错误的回调方法
  websock.onerror = function () {
    console.log("WebSocket连接发生错误");
     //createWebSocket();啊,发现这样写会创建多个连接,加延时也不行
  };
}
// 实际调用的方法
function sendSock(agentData ) {
  if (websock.readyState === websock.OPEN) {
    // 若是ws开启状态
    websocketsend(agentData);
  } else if (websock.readyState === websock.CONNECTING) {
    // 若是 正在开启状态,则等待1s后重新调用
    setTimeout(function () {
      sendSock(agentData);
    }, 1000);
  } else {
    // 若未开启 ,则等待1s后重新调用
    setTimeout(function () {
      sendSock(agentData);
    }, 1000);
  }
}
function closeSock() {
  websock.close();
}
// 数据接收
function websocketonmessage(msg) {
  // console.log("收到数据:"+JSON.parse(e.data));
  // console.log("收到数据:"+msg);
  // global_callback(JSON.parse(msg.data));
  // 收到信息为Blob类型时
  let result = null;
  // debugger
  if (msg.data instanceof Blob) {
    const reader = new FileReader();
    reader.readAsText(msg.data, "UTF-8");
    reader.onload = (e) => {
      result = JSON.parse(reader.result);
      //console.log("websocket收到", result);
      global_callback(result);
    };
  } else {
    result = JSON.parse(msg.data);
    //console.log("websocket收到", result);
    global_callback(result);
  }
}
// 数据发送
function websocketsend(agentData) {
  console.log("发送数据:" + agentData);
  websock.send(agentData);
}
// 关闭
function websocketclose(e) {
  console.log("connection closed (" + e.code + ")");
}
function websocketOpen(e) {
  console.log("连接打开");
}
export { sendSock, createWebSocket, closeSock };
 

4.使用Jwchat插件实现类似QQ、微信电脑端的功能

4.1步骤

安装依赖

npm i jwchat -S

main.js 引入配置

//element 必须引入
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
//聊天室-基于element
import Chat from 'jwchat';
Vue.use(Chat)

组件中使用

<template>
  <div class="jwchat">
    <!--
      v-model	输入框中的文字	String	-	""
      taleList	会话内容	Array	-	[]
      toolConfig	工具栏配置	Object	-	{}
      width	JwChat界面框宽度	string	-	750px
      height	JwChat界面框高度	string	-	570px
      config	组件配置	Object	-	{}
      scrollType	消息自动到低	String	scroll	noroll
      showRightBox	显示右边内容	Boolean	false	true
      winBarConfig	多窗口配置
      quickList   自动匹配快捷回复
      @enter	输入框点击就发送或者回车触发的事件	输入的原始数据
      @clickTalk	点击聊天框列中的用户和昵称触发事件	当前对话数据
     -->
    <JwChat-index
      v-model="inputMsg"
      :taleList="taleList"
      :config="config"
      :showRightBox="true"
      scrollType="scroll"
      :winBarConfig="winBarConfig"
      :quickList="config.quickList"
      @enter="bindEnter"
      @clickTalk="talkEvent"
    >
      <!-- 窗口右边栏 -->
      <JwChat-rightbox :config="rightConfig" @click="rightClick" />
      <!-- 快捷回复 -->
      <!-- <JwChat-talk :Talelist="talk" :config="quickConfig" @event="bindTalk" /> -->
      <!-- 工具栏自定义插槽 -->
      <template slot="tools">
        <div style="width: 20rem; text-align: right" @click="toolEvent(12)">
          <JwChat-icon type="icon-lishi" title="自定义" />
        </div>
      </template>
    </JwChat-index>
  </div>
</template>

<script>
const img = "https://www.baidu.com/img/flexible/logo/pc/result.png";
const listData = [

  {
    date: "2021/03/02 13:14:21",
    mine: false,
    name: "留恋人间不羡仙",
    img: "https://img0.baidu.com/it/u=3066115177,3339701526&fm=26&fmt=auto&gp=0.jpg",
    text: {
      system: {
        title: "在接入人工前,智能助手将为您首次应答。",
        subtitle: "猜您想问:",
        content: [
          {
            id: `system1`,
            text: "组件如何使用",
          },
          {
            id: `system2`,
            text: "组件参数在哪里查看",
          },
          {
            id: "system",
            text: "我可不可把组件用在商业",
          },
        ],
      },
    },
  },
];
function getListArr(size) {
  const listSize = listData.length;
  if (!size) {
    size = listSize;
  }
  let result = [];
  for (let i = 0; i < size; i++) {
    const item = listData[(Math.random() * listSize) >> 0];
    item.id = Math.random().toString(16).substr(-6);
    result.push(item);
  }
  return result;
}
export default {
  components: {},
  data() {
    return {
      // 输入框中的文字
      inputMsg: "",
      // 会话内容
      taleList: [],
      // 工具栏配置
      tool: {
        // show: ['file', 'history', 'img', ['文件1', '', '美图']],
        // showEmoji: false,
        callback: this.toolEvent,
      },
      // 组件配置
      config: {
        img: "https://img1.baidu.com/it/u=2109725846,3376113789&fm=26&fmt=auto&gp=0.jpg",
        name: "JwChat",
        dept: "最简单、最便捷",
        callback: this.bindCover,
        historyConfig: {
          show: true,
          tip: "滚动到顶时候显示的提示",
          callback: this.bindLoadHistory,
        },
        // 自动匹配快捷回复
        quickList: [

          { text: "外面的烟花奋力的燃着,屋里的人激情的说着情话", id: 10 },
          { text: "假如你是云,我就是雨,一生相伴,风风雨雨;", id: 11 },
          {
            text: "即使泪水在眼中打转,我依旧可以笑的很美,这是你学不来的坚强。",
            id: 12,
          },
          {
            text: " 因为不知来生来世会不会遇到你,所以今生今世我会加倍爱你。",
            id: 13,
          },
        ],
      },

    };
  },
  methods: {
    // 切换用户窗口,加载对应的历史记录
    bindWinBar(play = {}) {
      const { type, data = {} } = play;
      console.log(play);
      if (type === "winBar") {
        const { id, dept, name, img } = data;
        this.config = { ...this.config, id, dept, name, img };
        this.winBarConfig.active = id;
        if (id === "win00") {
          this.taleList = getListArr();
        } else this.taleList = getListArr((Math.random() * 4) >> 0);
      }
      if (type === "winBtn") {
        const { target: { id } = {} } = data;
        const { list } = this.winBarConfig;
        this.winBarConfig.list = list.reduce((p, i) => {
          if (id != i.id) p.push(i);
          return p;
        }, []);
      }
    },
    // 点击聊天框列中的用户和昵称触发事件
    talkEvent(play) {
      console.log(play);
    },
    // 输入框点击就发送或者回车触发的事件
    bindEnter(e) {
      console.log(e);
      const msg = this.inputMsg;
      if (!msg) return;
      const msgObj = {
        date: "2020/05/20 23:19:07",
        text: { text: msg },
        mine: true,
        name: "JwChat",
        img: "https://img1.baidu.com/it/u=31094377,222380373&fm=26&fmt=auto&gp=0.jpg",
      };
      this.taleList.push(msgObj);
    },

    /**
     * @description: 点击加载更多的回调函数
     * @param {*}
     * @return {*}
     */
    bindLoadHistory() {
      const history = new Array(3).fill().map((i, j) => {
        return {
          date: "2020/05/20 23:19:07",
          text: { text: j + new Date() },
          mine: false,
          name: "JwChat",
          img: "https://img1.baidu.com/it/u=31094377,222380373&fm=26&fmt=auto&gp=0.jpg",
        };
      });
      let list = history.concat(this.list);
      this.taleList = list;
      console.log("加载历史", list, history);
    },
    /**
     * @description:
     * @param {*} type 当前点击的按钮
     * @param {*} plyload 附加文件或者需要处理的数据
     * @return {*}
     */
    toolEvent(type, plyload) {
      console.log("tools", type, plyload);
    },
    bindCover(event) {
      console.log("header", event);
    },
    rightClick(type) {
      console.log("rigth", type);
    },
  },
  mounted() {
    this.taleList = getListArr();
  },
};
</script>

<style>
.jwchat {
  height: 100vh;
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

5.动画效果

吸附效果

使用v-show绑定变量控制显示隐藏

 // 吸附效果
    xiFu () {
      setTimeout(() => {
        //10秒后自动隐藏小空间转为吸附效果
        this.isMouse = false
      }, 5000)
    },
@keyframes move {
  0% {
    transform: translateX(0px) rotateY(20deg);
  }
  100% {
    transform: translateX(1.0417rem) rotateY(180deg);
  }
}

.cssDongHua {
  animation: move 2s linear 1s 1 alternate forwards;
}
//template
:class="isMouse ? '' : 'cssDongHua'"
        @click="isOpen = !isOpen"
        v-show="!isOpen"
        @mouseenter="isMouse = true"

到此这篇关于vue基于websocket实现智能聊天及吸附动画效果的文章就介绍到这了,更多相关vue websocket智能聊天吸附动画内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 基于node+vue实现简单的WebSocket聊天功能

    首先,我需要用到node的nodejs-websocket模块 使用yarn进行安装 yarn add nodejs-websocket --save 当然,你也可以用npm进行安装 npm i nodejs-websocket --save 安装完毕之后,我们开始写服务端的代码,首先,我用node在本地起了一个node服务器用来开启websocket服务 sock.js: let ws = require("nodejs-websocket"); console.log("

  • Vue +WebSocket + WaveSurferJS 实现H5聊天对话交互的实例

    引言 在与实现了语音合成.语义分析.机器翻译等算法的后端交互时,页面可以设计成更为人性化.亲切的方式.我们采用类似于聊天对话的实现,效果如下: 智能客服(输入文本,返回引擎处理后的文本结果) 语音合成(输入文本,返回文本以及合成的音频) 如上图所示,返回文本后,再返回合成出的音频. 音频按钮嵌在对话气泡中,可以点击播放. 语音识别(在页面录制语音发送,页面实时展示识别出的文本结果) 实现功能及技术要点 1.基于WebSocket实现对话流 页面与后端的交互是实时互动的,所以采用WebSocket

  • Vue+Websocket简单实现聊天功能

    本文实例为大家分享了Vue+Websocket简单实现聊天功能的具体代码,供大家参考,具体内容如下 效果图: 聊天室 此篇文章是针对Websocket的简单了解和应用,利用Nodejs简单搭建一个服务器加以实现. 首先创建一个vue项目 然后再创建一个server文件夹,在终端上打开该文件夹,输入vue init(一直敲 "回车" 键),最后再建一个server.js文件,如下图 代码如下: server.js/ 在server文件终端下 npm install --s ws var

  • vue使用WebSocket模拟实现聊天功能

    效果展示 两个浏览器相互模拟 1.创建模拟node服务 在vue根目录下创建 server.js 文件模拟后端服务器 **在server终端目录下载 ** npm install --s ws 2.编写server.js文件 代码如下 var userNum = 0; //统计在线人数 var chatList = [];//记录聊天记录 var WebSocketServer = require('ws').Server; wss = new WebSocketServer({ port: 8

  • websocket+Vuex实现一个实时聊天软件

    目录 前言 一.效果如图 二.具体实现步骤 1.引入Vuex 2.webscoked实现 总结 前言 这篇文章主要利用websocked 建立长连接,利用Vuex全局通信的特性,以及watch,computed函数监听消息变化,并驱动页面变化实现实时聊天. 一.效果如图 二.具体实现步骤 1.引入Vuex 代码如下(示例): //安装vuex npm install vuex //main.js 中引入 import store from './store' new Vue({ el: '#ap

  • 基于vue和websocket的多人在线聊天室

    最近看到一些关于websocket的东西,就决定写一个在线聊天室尝试一下.最终决定配合vue来写,采用了官方的vue脚手架vue-cli和官方的router,在本例中呢,我是用了CHAT这个对象来存储app的数据的,但后来一想,虽然项目很小,但如果用官方的vuex会更好,方便以后扩展,比如可以加上私信功能,可以在对方不在线的时候缓存发送的消息,这些都是可以的.(现在比较尴尬的就是,我把聊天室写好放到公众号号redream里,但是很少有人会同时在线,所以你会经常发现你进去的时候只有你一个人,就导致

  • vue实现websocket客服聊天功能

    本文章主要介绍如何实现一个基本的聊天,后续会添加表情包,传照片等功能 其实刚开始接触的时候,我最大的疑惑是聊天功能的前期是否需要搭建什么框架.下载一些什么东西之类的,结果就是,其实websocket可以直接使用,然后前后端搭配,也是免费的,暂时没发现需要收费功能的东西. 实现效果图: 首先封装一个websocket.js文件(大家可以直接复制,然后把接收/发送数据之类的格式改成自己的就可以啦) import store from '@/store' var webSocket = null; v

  • vue基于websocket实现智能聊天及吸附动画效果

    目录 前言: 1.效果如下: 2.主要功能: 2.1.基于websocket实现聊天功能,封装了一个socket.js文件 2.2使用Jwchat插件实现类似QQ.微信电脑端的功能 2.3动画效果(如关闭打开时动画.吸附效果及其他效果) 3.实现步骤: 3.1.实现websocket聊天功能 3.2.在页面中的使用方法: 关闭连接 发送给后端的方法 4.使用Jwchat插件实现类似QQ.微信电脑端的功能 4.1步骤 5.动画效果 前言: 发现这篇文章写的有点多,我总结一下整体思路: 首先这个功能

  • php基于websocket搭建简易聊天室实践

    本文实例讲述了php基于websocket搭建简易聊天室实践.分享给大家供大家参考.具体如下: 1.前言 公司游戏里面有个简单的聊天室,了解了之后才知道是node+websocket做的,想想php也来做个简单的聊天室.于是搜集各种资料看文档.找实例自己也写了个简单的聊天室. http连接分为短连接和长连接.短连接一般可以用ajax实现,长连接就是websocket.短连接实现起来比较简单,但是太过于消耗资源.websocket高效不过兼容存在点问题.websocket是html5的资源 2.前

  • Vue基于vuex、axios拦截器实现loading效果及axios的安装配置

    准备 利用vue-cli脚手架创建项目 进入项目安装vuex.axios(npm install vuex,npm install axios) axios配置 项目中安装axios模块(npm install axios)完成后,进行以下配置: main.js //引入axios import Axios from 'axios' //修改原型链,全局使用axios,这样之后可在每个组件的methods中调用$axios命令完成数据请求 Vue.prototype.$axios=Axios l

  • vue中使用animate.css实现炫酷动画效果

    目录 1.安装(在vscode终端中,使用npm安装) 2.引入 3.代码实现 animate.css 是一个来自国外的 CSS3 动画库,它提供了抖动(shake).闪烁(flash).弹跳(bounce).翻转(flip).旋转(rotateIn/rotateOut).淡入淡出(fadeIn/fadeOut)等多达 60 多种动画效果,几乎包含了所有常见的动画效果.这些效果在大多数支持CSS3的浏览器上都能保持一致.简单来说,我们使用它,只需要写很少的代码,就可以实现非常炫酷的动画效果. 官

  • .NET Core 基于Websocket的在线聊天室实现

    什么是Websocket 我们在传统的客户端程序要实现实时双工通讯第一想到的技术就是socket通讯,但是在web体系是用不了socket通讯技术的,因为http被设计成无状态,每次跟服务器通讯完成后就会断开连接. 在没有websocket之前web系统如果要做双工通讯往往使用http long polling技术.http long polling 每次往服务器发送请求后,服务端不会立刻返回信息来结束请求,而是一直挂着直到有数据需要返回,或者等待超时了才会返回.客户端在结束上一次请求后立刻再发

  • 基于websocket实现简单聊天室对话

    本文实例为大家分享了vue + element ui 实现锚点定位的具体代码,供大家参考,具体内容如下 首先搭建一个node的环境,在app.js中写入以下代码 npm install socket.io-client socket是一个高性能的服务器框架,开发者只要实现一两个接口,便可以开发出自己的网络应用,例如Rpc服务.聊天室服务器.手机游戏服务器等. npm install http-server 一般提供server服务,参数可以指定端口.地址等等,例如指定服务在8888端口启动,命令

  • 基于JS实现Android,iOS一个手势动画效果

    废话不多说了,先给大家展示下效果图: 这是iOS下的效果,android下完全一致.通过do_GestureView组件和do_Animation组件,deviceone能很容易实现复杂的跨平台纯原生动画效果,这个示例就是通过手势控制图片上下动画滑动实现开合效果,还支持声音效果. 下面是主要的代码 //index.ui.js var do_Animator1 = mm("do_Animator"); do_Animator1.append(500, { y: -1334, curve:

  • 基于javascript实现漂亮的页面过渡动画效果附源码下载

    用户通过点击页面左侧的菜单,对应的页面加载时伴随着滑动过滤动画,并带有进度条效果.当然页面的加载是Ajax驱动的,整个加载过渡过程非常流畅,非常好的用户体验. HTML HTML结构中,.cd-main包含页面主体内容,.cd-side-navigation包含着侧边导航条,#cd-loading-bar则是用来做进度条动画用的. <nav class="cd-side-navigation"> <ul> <li> <a href="

随机推荐