最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue基于websocket實現(xiàn)智能聊天及吸附動畫效果

 更新時間:2022年07月08日 09:29:13   作者:接著奏樂接著舞。  
這篇文章主要介紹了vue基于websocket實現(xiàn)智能聊天及吸附動畫效果,主要功能是基于websocket實現(xiàn)聊天功能,封裝了一個socket.js文件,使用Jwchat插件實現(xiàn)類似QQ、微信電腦端的功能,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下

前言:

發(fā)現(xiàn)這篇文章寫的有點多,我總結(jié)一下整體思路:

首先這個功能市面上挺多的,我是參考了幾家公司的功能實現(xiàn),發(fā)現(xiàn)他們的整體功能實現(xiàn)和下面我的截圖類似。

首先核心功能是基于websocket實現(xiàn)用戶輸入文字服務(wù)器根據(jù)用戶輸入返回數(shù)據(jù)渲染在頁面上,而這個功能我不推薦直接使用原生,而是使用封裝好的,就像文章里封裝的socket.js,這個文件很簡單就對外提供三個方法,一個是和后端通信連接,再一個是接收后端的數(shù)據(jù),最后一個是發(fā)送數(shù)據(jù)給后端。

其次,我們需要一個聊天框,我使用的Jwchat插件,優(yōu)點是功能比較全類似QQ聊天,使用方法也很簡單,但是話說回來,這個插件的很多樣式需要修改,尤其對于要做頁面適配的項目,所以這個插件不是特別推薦,還有一個點就是他沒有關(guān)閉按鈕,做的比較粗糙,我是通過在生命周期中使用原生JS添加的關(guān)閉圖標(biāo),然后再通過watch動態(tài)的選擇要不要創(chuàng)建刪除按鈕。

最后說一下動畫,其實就是一個聊天框,一個小框,通過點擊使v-show綁定的變量來實現(xiàn)切換效果。這個吸附效果是我用CSS動畫將原本的一個長方形框框翻轉(zhuǎn)180度后在平移模擬吸附效果,其實正兒八經(jīng)做的話需要計算頁面寬度和元素位置計算出一個比例然后再設(shè)置一個動畫效果,這個GitHub上還是有挺多的,注意的是很多實現(xiàn)都是移動端的,PC端用不了,是個坑。再一個動畫就是打開關(guān)閉時的效果,使用的是elementUI自帶的動畫效果。

1.效果如下:

2.主要功能:

2.1.基于websocket實現(xiàn)聊天功能,封裝了一個socket.js文件

2.2使用Jwchat插件實現(xiàn)類似QQ、微信電腦端的功能

(其實并不是很好用,但考慮到后續(xù)可能會使用其功能就先用了)

2.3動畫效果(如關(guān)閉打開時動畫、吸附效果及其他效果)

3.實現(xiàn)步驟:

3.1.實現(xiàn)websocket聊天功能

首先封裝了一個socket.js文件;需要主要的是將socket.js中URL修改成自己的

封裝的websocke暴露三個接口

  • sendSock用于發(fā)送數(shù)據(jù),發(fā)給后端
  • createWebSocket用于創(chuàng)建連接、接收數(shù)據(jù)并進(jìn)行處理
  • closeSock 用于關(guān)閉連接

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

第一步:導(dǎo)入文件

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

第二步:初始化時建立websocket連接

created() {
    this.init();
    ......
  },
  methods: {
    init() {
      createWebSocket(this.global_callback);
      ......
    },
 
    // websocket的回調(diào)函數(shù),msg表示收到的消息
    global_callback(msg) {
      console.log("收到服務(wù)器信息:" + msg);
    },
  },

關(guān)閉連接

closeSock();

發(fā)送給后端的方法

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();
  };
  // 連接發(fā)生錯誤的回調(diào)方法
  websock.onerror = function () {
    console.log("WebSocket連接發(fā)生錯誤");
     //createWebSocket();啊,發(fā)現(xiàn)這樣寫會創(chuàng)建多個連接,加延時也不行
  };
}
// 實際調(diào)用的方法
function sendSock(agentData ) {
  if (websock.readyState === websock.OPEN) {
    // 若是ws開啟狀態(tài)
    websocketsend(agentData);
  } else if (websock.readyState === websock.CONNECTING) {
    // 若是 正在開啟狀態(tài),則等待1s后重新調(diào)用
    setTimeout(function () {
      sendSock(agentData);
    }, 1000);
  } else {
    // 若未開啟 ,則等待1s后重新調(diào)用
    setTimeout(function () {
      sendSock(agentData);
    }, 1000);
  }
}
function closeSock() {
  websock.close();
}
// 數(shù)據(jù)接收
function websocketonmessage(msg) {
  // console.log("收到數(shù)據(jù):"+JSON.parse(e.data));
  // console.log("收到數(shù)據(jù):"+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);
  }
}
// 數(shù)據(jù)發(fā)送
function websocketsend(agentData) {
  console.log("發(fā)送數(shù)據(jù):" + agentData);
  websock.send(agentData);
}
// 關(guān)閉
function websocketclose(e) {
  console.log("connection closed (" + e.code + ")");
}
function websocketOpen(e) {
  console.log("連接打開");
}
export { sendSock, createWebSocket, closeSock };
 

4.使用Jwchat插件實現(xiàn)類似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	會話內(nèi)容	Array	-	[]
      toolConfig	工具欄配置	Object	-	{}
      width	JwChat界面框?qū)挾?string	-	750px
      height	JwChat界面框高度	string	-	570px
      config	組件配置	Object	-	{}
      scrollType	消息自動到低	String	scroll	noroll
      showRightBox	顯示右邊內(nèi)容	Boolean	false	true
      winBarConfig	多窗口配置
      quickList   自動匹配快捷回復(fù)
      @enter	輸入框點擊就發(fā)送或者回車觸發(fā)的事件	輸入的原始數(shù)據(jù)
      @clickTalk	點擊聊天框列中的用戶和昵稱觸發(fā)事件	當(dāng)前對話數(shù)據(jù)
     -->
    <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" />
      <!-- 快捷回復(fù) -->
      <!-- <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: "在接入人工前,智能助手將為您首次應(yīng)答。",
        subtitle: "猜您想問:",
        content: [
          {
            id: `system1`,
            text: "組件如何使用",
          },
          {
            id: `system2`,
            text: "組件參數(shù)在哪里查看",
          },
          {
            id: "system",
            text: "我可不可把組件用在商業(yè)",
          },
        ],
      },
    },
  },
];
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: "",
      // 會話內(nèi)容
      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,
        },
        // 自動匹配快捷回復(fù)
        quickList: [
        
          { text: "外面的煙花奮力的燃著,屋里的人激情的說著情話", id: 10 },
          { text: "假如你是云,我就是雨,一生相伴,風(fēng)風(fēng)雨雨;", id: 11 },
          {
            text: "即使淚水在眼中打轉(zhuǎn),我依舊可以笑的很美,這是你學(xué)不來的堅強(qiáng)。",
            id: 12,
          },
          {
            text: " 因為不知來生來世會不會遇到你,所以今生今世我會加倍愛你。",
            id: 13,
          },
        ],
      },
 
    };
  },
  methods: {
    // 切換用戶窗口,加載對應(yīng)的歷史記錄
    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;
        }, []);
      }
    },
    // 點擊聊天框列中的用戶和昵稱觸發(fā)事件
    talkEvent(play) {
      console.log(play);
    },
    // 輸入框點擊就發(fā)送或者回車觸發(fā)的事件
    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: 點擊加載更多的回調(diào)函數(shù)
     * @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 當(dāng)前點擊的按鈕
     * @param {*} plyload 附加文件或者需要處理的數(shù)據(jù)
     * @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秒后自動隱藏小空間轉(zhuǎn)為吸附效果
        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"

到此這篇關(guān)于vue基于websocket實現(xiàn)智能聊天及吸附動畫效果的文章就介紹到這了,更多相關(guān)vue websocket智能聊天吸附動畫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue element-ui父組件控制子組件的表單校驗操作

    Vue element-ui父組件控制子組件的表單校驗操作

    這篇文章主要介紹了Vue element-ui父組件控制子組件的表單校驗操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • 關(guān)于ElementUI自定義Table支持render

    關(guān)于ElementUI自定義Table支持render

    這篇文章主要介紹了關(guān)于ElementUI自定義Table支持render,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • vue中@路徑無法跳轉(zhuǎn)到指定文件的解決

    vue中@路徑無法跳轉(zhuǎn)到指定文件的解決

    這篇文章主要介紹了vue中@路徑無法跳轉(zhuǎn)到指定文件的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • 實現(xiàn)一個 Vue 吸頂錨點組件方法

    實現(xiàn)一個 Vue 吸頂錨點組件方法

    這篇文章主要介紹了實現(xiàn)一個 Vue 吸頂錨點組件方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • VUE中Echarts的resize事件報錯和移除windows的事件問題

    VUE中Echarts的resize事件報錯和移除windows的事件問題

    這篇文章主要介紹了VUE中Echarts的resize事件報錯和移除windows的事件問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • vue中如何給data里面的變量增加屬性

    vue中如何給data里面的變量增加屬性

    這篇文章主要介紹了vue中如何給data里面的變量增加屬性,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • vue實現(xiàn)打印功能的兩種方法

    vue實現(xiàn)打印功能的兩種方法

    這篇文章主要介紹了vue實現(xiàn)打印功能的兩種方法,文中通過兩種方法給大家介紹了指定不打印區(qū)域的解決方法,需要的朋友可以參考下
    2018-09-09
  • 關(guān)于Vue?CLI3中啟動cli服務(wù)參數(shù)說明

    關(guān)于Vue?CLI3中啟動cli服務(wù)參數(shù)說明

    這篇文章主要介紹了關(guān)于Vue?CLI3中啟動cli服務(wù)參數(shù)說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue.js中computed的基本使用方法

    Vue.js中computed的基本使用方法

    Vue.js中,computed屬性根據(jù)依賴進(jìn)行緩存,只有依賴改變時才重新計算,這樣有效提高性能,computed屬性是響應(yīng)式的,可以自動更新,并且默認(rèn)是只讀的,它與methods的主要區(qū)別在于計算屬性具有緩存性,而方法每次調(diào)用都會執(zhí)行,使用computed可以使模板更加簡潔,提高應(yīng)用性能
    2024-09-09
  • 關(guān)于Vue組件庫開發(fā)詳析

    關(guān)于Vue組件庫開發(fā)詳析

    這篇文章主要給大家介紹了關(guān)于Vue組件庫開發(fā)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用vue具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07

最新評論

广平县| 桐梓县| 汶川县| 蒙城县| 临沂市| 肃北| 华容县| 柏乡县| 神木县| 淮安市| 犍为县| 玛曲县| 江油市| 漾濞| 珲春市| 开封县| 临沂市| 敖汉旗| 屯门区| 老河口市| 昌江| 谢通门县| 新源县| 高阳县| 波密县| 昆山市| 图片| 浦北县| 白玉县| 海林市| 武城县| 清流县| 翼城县| 当雄县| 东光县| 安陆市| 泗水县| 丰城市| 江川县| 和林格尔县| 徐闻县|