vue集成leancloud实时通信开发指南JavaScript 简易通信demo

leancloud实时通信开发指南JavaScript 简易通信demo-github地址:
https://github.com/walk-liuyan/simple-leancloud-realtime-demo

leancloud demo没有用vue的例子。只有原生和angular。但公司项目使用vue,那就自己根据文档撸一个简易的通信(拉取聊天记录,发、收信息),模式属于N个用户找公司客服唠嗑。此文章仅作为了解leancloud im允许流程作为出发点的例子。具体扩展,请自行拓展,也可留言 互相学习。

我对leancloud Im了解的奔跑流程:
1、引入leancloud real sdk
2、配置key appid
3、拉取所有会话
4、根据会话,拉取初始聊天记录
5、建立接收信息
6、发送信息

<template>
  <div>
 <div class="messageBox p-l-20 p-r-20">
      <div v-for="(item,index) in messages" :key="index" class="itemMessageBox">
        <div class="sendTime tc fz34">{{item.updatedAt|dateFormat('YYYY-MM-DD  hh:mm:ss')}}</div>
        <div class="sendMsgBox"
        :class="{'mineMsg':item.from === curUserChatId }">
          <div class="itemMsg fz36">{{item._lctext}}</div>
        </div>
      </div>
       <div id="messageViewBottom" ref="messageViewBottom"></div>
    </div>
    <div class="sendMsgBtnBox bg-white w-100 p-l-10 p-r-10">
      <div class="leftInput">
       <textarea class="w-100"
                 v-model="draft"
                 placeholder="说点什么……"
                 @keyup.enter="sendMsg(draft)"
       ></textarea>
      </div>
      <div class="sendBtn text-middle fz36" @click="sendMsg(draft)">
        <img src="/static/chat/chatSend.png" style="width: 50%;">
      </div>
    </div>
      </div>
</template>
<script type="text/babel">
/* 引入要使用的东西 */
import { Realtime, TextMessage } from "leancloud-realtime";
import { ImageMessage } from "leancloud-realtime-plugin-typed-messages";
import AV, { Object } from "leancloud-storage";
import { TypingStatusMessage } from "./js/typing-indicator";
import StickerMessage from "./js/sticker-message";
import userService from "./js/user.service";
import FilterMixins from "@/assets/js/filters-mixins";
import FnMixins from "@/assets/js/fn-mixins";
import _ from "lodash";
import { setTimeout } from "timers";
export default {
  components: {},
  data() {
    return {
      curUserChatId: "", // 当前用户的chatId
      curChatWidthUserId: this.$route.query.id, // 和谁聊天的chatId
      draft: "",
      messages: [],
      LeanRTImClient: null,
      pageYOffset: 0,
      messageIterator: null
    };
  },
  computed: {},
  methods: {
      // 发送信息
       sendMsg(draft) {
      const that = this;
      console.log("send this.curConversation", this.curConversation);
      this.curConversation
        .send(new TextMessage(draft))
        .then(function(message, conversation) {
          console.log("用户  & 环球理事 ", "发送成功!", message, conversation);
          that.messages.push(message);
          that.draft = "";
          that.scrollToBottom();
        })
        .catch(console.error);
        /*
         realtime
          .createIMClient("环球理事")
          .then(function(tom) {
            console.log("tom imclinet", tom);
            return tom.createConversation({
              members: [`${that.curUserChatId}`],
              name: `环球理事 => ${that.curUserChatId}`
            });
          })
          .then(function(conversation) {
            console.log("conversation", conversation);
            return conversation.send(new TextMessage(draft));
          })
          .then(function(message, conversation) {
            console.log("环球理事 & 用户", "发送成功!", message);
            that.msgToConversation(message);
            that.draft = "";
            that.scrollToBottom();
          })
          .catch(console.error);
        */
    },
      // 接收信息
    acceptMsg() {
      console.log("acceptMsg");
      const that = this;
      this.LeanRTImClient.then(function(jerry) {
        console.log("用户", jerry);
        jerry.on("message", function(message, conversation) {
          that.messageIterator = conversation.createMessagesIterator({
            limit: 10
          });
          that.messageIterator
            .next()
            .then(function(result) {
              console.log("cur-result", result);
              that.messages = result.value;
            })
            .catch(console.error.bind(console));
          // 第一次调用 next 方法,获得前 10 条消息,还有更多消息,done 为 false
          that.loadMoreChatMsg();

          console.log("Message received: " + message, conversation);
          console.log("received", message.text);
          that.scrollToBottom();
        });
      }).catch(console.error);
    },
      // init当前对话的历史记录
    initChatMsg() {
      const that = this;
      that.messageIterator
        .next()
        .then(function(result) {
          that.messages = result.value.concat(that.messages);
          console.log("init data", result.value);
          setTimeout(() => {
            that.scrollToBottom();
          }, 100);
        })
        .catch(console.error.bind(console));
    },
      // 加载更多的聊天记录
    loadMoreChatMsg() {
      const that = this;
      that.messageIterator
        .next()
        .then(function(result) {
          that.messages = result.value.concat(that.messages);
          console.log("laqu data", result.value);
        })
        .catch(console.error.bind(console));
    },
    getNormalConvs(imClient) {
      return imClient
        .getQuery()
        .withLastMessagesRefreshed()
        .containsMembers([imClient.id])
        .find();
    },
//  拉取对话
    getConversations(imClient) {
      const that = this;
      return Promise.all([this.getNormalConvs(imClient)]).then(datas => {
        console.log("_createdAt", _.orderBy(datas[0], ["_createdAt"], ["asc"]));
        console.log(datas[0]);
        if (datas[0].length === 0) {
          that.curConversation = this.LeanRTImClient.then(function(imClient) {
            console.log("创建会话", imClient);
            return imClient.createConversation({
              members: ["环球理事"],
              name: `${that.curUserChatId} => 环球理事 `
            });
          });
        } else {
          that.curConversation = datas[0][0];
          console.log("promise that.curConversation", that.curConversation);
        }
        that.messageIterator = that.curConversation.createMessagesIterator({
          limit: 10
        });
        that.initChatMsg(); // 拉去初始历史数据
      });
    },
// 滚动到底部
    scrollToBottom() {
      const elBottom = document.getElementById("messageViewBottom");
      const pageYOffset = elBottom.offsetTop;
      setTimeout(() => {
        window.scroll(0, pageYOffset);
      }, 0);
    }
  },
  mounted() {
// 监听页面的滚动,如果上拉到头部,就加载历史记录
    window.onscroll = () => {
      this.pageYOffset = window.pageYOffset;
      if (this.pageYOffset < 30) {
        /* 加载更多数据 */
        this.loadMoreChatMsg(); // 上拉加载历史数据
      }
    };
  },
  created() {
    this.setHtmlTitle(this.curChatWidthUserId);
// 这是我自己写的方法,用于设置html title
    const curBrowser = this._curBrowser();// 这是我自己写的方法,用于判断当前环境
    const curUserInfo = JSON.parse(window.localStorage.getItem("curUserInfo"));
    if (curUserInfo) {
// 获取当前用户的ChatID
      this.curUserChatId = curUserInfo.binding_chat_id;
    } else {
// 这是我自己写的方法,如果没有用户信息,就去微信授权等
      if (curBrowser === "wechat") {
        this._setUserStatus;
      }
    }
    this.LeanRTImClient = realtime.createIMClient(this.curUserChatId);
    this.LeanRTImClient.then(function(imClient) {
        // 拉取历史会话
      that.getConversations(imClient);
    });
    this.acceptMsg();
    console.log("from", this.curUserChatId, "to", this.curChatWidthUserId);
  },
  mixins: [FilterMixins, FnMixins]
};
</script>
<style lang='scss' scoped>
h1,
h2 {
  font-weight: normal;
}

ul {
  list-style-type: none;
  padding: 0;
}

li {
  display: inline-block;
  margin: 0 10px;
}

a {
  color: #42b983;
}

$arrow-size: 8px;
$background: #f6f6f6;

.messageBox {
  margin-bottom: 1.5rem;
  .itemMessageBox {
    margin: 0.7rem 0;
    .sendTime {
    }
    .sendMsgBox {
      display: flex;
      justify-content: flex-start;
      .itemMsg {
        position: relative;
        max-width: 5rem;
        min-height: 37px;
        padding: 0.1rem;
        margin: 0.06rem 0 0;
        background: #f6f6f6;
        word-wrap: break-word;
        &:after {
          content: "";
          display: block;
          position: absolute;
          top: -$arrow-size;
          left: 0;
          border: $arrow-size solid transparent;
          border-width: 0 $arrow-size $arrow-size 0;
          border-bottom-color: $background;
        }
      }
    }
    .mineMsg {
      display: flex;
      justify-content: flex-end;
      .itemMsg {
        background: #2c97e8;
        color: white;
        &:after {
          border-bottom-color: #f6f6f6;
          top: auto;
          left: auto;
          bottom: -8px;
          right: 0;
          border: 8px solid transparent;
          border-width: 8px 0 0 8px;
          border-top-color: #2c97e8;
        }
      }
    }
  }
}

.sendMsgBtnBox {
  position: fixed;
  bottom: 0px;
  height: 1.2rem;
  display: flex;
  .leftInput {
    flex: 1;
    textarea {
      font-size: 0.32rem;
      max-height: 1.6rem;
      min-height: 0.56rem;
      -ms-flex-preferred-size: auto;
      resize: none;
      overflow-y: scroll;
      color: rgba(0, 0, 0, 0.87);
      border-color: rgba(0, 0, 0, 0.12);
      -ms-flex-order: 2;
      order: 2;
      display: block;
      margin-top: 0;
      background: none;
      padding: 0.04rem;
      border-width: 0 0 0.01rem 0;
      line-height: 0.52rem;
      -ms-flex-preferred-size: 0.52rem;
      border-radius: 0;
      border-style: solid;
      width: 100%;
      box-sizing: border-box;
      float: left;
    }
  }
  .sendBtn {
    width: 1.5rem;
  }
}
</style>


实现效果

image.png

之前公司是用网易云信IM,我就写了一个自定义形式的IM(vue+ webpack+iview + im)
文章地址如下:
https://www.jianshu.com/p/3914f1a8e1ef
https://www.jianshu.com/p/d56de7ea9736
网易云信demo地址如下:https://github.com/walk-liuyan/vue-im

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容