vue.js仿微信聊天窗口展示組件

源碼:https://github.com/doterlin/vue-wxChat
演示地址:https://doterlin.github.io/vue-wxChat/

演示截圖

運行

# install dependencies
npm install

# serve with hot reload at localhost:8080
npm run dev

# build for production with minification
npm run build

介紹

  • 支持文本和圖片的展示(后續(xù)將支持對語音類的展示)。
  • 支持滾動加載數(shù)據(jù),其中滾動加載依賴我另外一個組件scrollLoader.vue(《Vue.js上下滾動加載組件》)。
  • 支持QQ表情,為了能使用表情請全局注冊指令v-emotion,我在main.js做了實現(xiàn);代碼如下:
function toEmotion(text, isNoGif){
    var list = ['微笑', '撇嘴', '色', '發(fā)呆', '得意', '流淚', '害羞', '閉嘴', '睡', '大哭', '尷尬', '發(fā)怒', '調(diào)皮', '呲牙', '驚訝', '難過', '酷', '冷汗', '抓狂', '吐', '偷笑', '愉快', '白眼', '傲慢', '饑餓', '困', '驚恐', '流汗', '憨笑', '大兵', '奮斗', '咒罵', '疑問', '噓', '暈', '折磨', '衰', '骷髏', '敲打', '再見', '擦汗', '摳鼻', '鼓掌', '糗大了', '壞笑', '左哼哼', '右哼哼', '哈欠', '鄙視', '委屈', '快哭了', '陰險', '親親', '嚇', '可憐', '菜刀', '西瓜', '啤酒', '籃球', '乒乓', '咖啡', '飯', '豬頭', '玫瑰', '凋謝', '示愛', '愛心', '心碎', '蛋糕', '閃電', '炸彈', '刀', '足球', '瓢蟲', '便便', '月亮', '太陽', '禮物', '擁抱', '強', '弱', '握手', '勝利', '抱拳', '勾引', '拳頭', '差勁', '愛你', 'NO', 'OK', '愛情', '飛吻', '跳跳', '發(fā)抖', '慪火', '轉(zhuǎn)圈', '磕頭', '回頭', '跳繩', '揮手', '激動', '街舞', '獻吻', '左太極', '右太極', '嘿哈', '捂臉', '奸笑', '機智', '皺眉', '耶', '紅包', '雞'];
    if (!text) {
        return text;
    }

    text = text.replace(/\[[\u4E00-\u9FA5]{1,3}\]/gi, function(word){
        var newWord = word.replace(/\[|\]/gi,'');
        var index = list.indexOf(newWord);
        var backgroundPositionX = -index * 24
        var imgHTML = '';
        if(index<0){
            return word;
        }

        if (isNoGif) {
            if(index>104){
                return word;
            }
            imgHTML = `<i class="static-emotion" style="background:url(https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/default218877.gif) ${backgroundPositionX}px 0;"></i>`
        } else {
            var path = index>104 ? '/img' : 'https://res.wx.qq.com/mpres/htmledition/images/icon';
            imgHTML = `![](${path}/emotion/${index}.gif)`
        }
        return imgHTML;
    });
    return text;
}


Vue.directive('emotion', {
    bind: function (el, binding) {
        el.innerHTML = toEmotion(binding.value)
    }
});

如何使用?

參數(shù)已經(jīng)在組件中做了說明,并在App.vue中做了演示:
參數(shù)和說明:
微信聊天可視化組件
依賴scrollLoader組件, 依賴指令v-emotion(實現(xiàn)請查看main.js)

參數(shù)
width 組件寬度,默認450
wrapBg 外層父元素背景顏色,默認#efefef
maxHeight 展示窗口最高高度, 默認900
contactAvatarUrl 好友頭像url
ownerAvatarUrl 微信主人頭像url
ownerNickname 微信主人昵稱
getUpperData (必需)當滾動到上方時加載數(shù)據(jù)的方法,返回值要為Promise對象,resolve的結(jié)構(gòu)同data
getUnderData (必需)當滾動到下方時加載數(shù)據(jù)的方法,返回值同上
data (必需)傳入初始化數(shù)據(jù), 結(jié)構(gòu)如下:

[{
    direction: 2, //為2表示微信主人發(fā)出的消息,1表示聯(lián)系人
    id: 1, //根據(jù)這個來排序消息
    type: 1, //1為文本,2為圖片
    content: '你好!![呲牙]', //當type為1時這里是文本消息,當type2為2時這里要存放圖片地址;后續(xù)會支持語音的顯示
    ctime: new Date().toLocaleString() //顯示當前消息的發(fā)送時間
},
{
    direction: 1,
    id: 2,
    type: 1,
    content: '你也好。[害羞]',
    ctime: new Date().toLocaleString()
}]

完整的使用實例

效果:https://doterlin.github.io/vue-wxChat/
代碼:

//主文件,對wxChat的用法做示例

<template>
<wxChat 
  :data="wxChatData"
  :showShade="false"
  contactNickname="簡叔"
  :getUpperData="getUpperData"
  :getUnderData="getUnderData"
  :ownerAvatarUrl="ownerAvatarUrl"
  :contactAvatarUrl="contactAvatarUrl"
  :width="420">
</wxChat>
</template>

<script>
import wxChat from './components/wxChat.vue'

export default {
  name: 'app',
  data () {
    return {
      upperTimes: 0,
      underTimes: 0,
      upperId: 0,
      underId: 6,
      ownerAvatarUrl: './src/assets/avatar1.png',
      contactAvatarUrl: './src/assets/avatar2.png',
      wxChatData: [{
        direction: 2,
        id: 1,
        type: 1,
        content: '你好!![呲牙]',
        ctime: new Date().toLocaleString()
      },
      {
        direction: 1,
        id: 2,
        type: 1,
        content: '你也好。[害羞]',
        ctime: new Date().toLocaleString()
      },
      {
        direction: 2,
        id: 3,
        type: 1,
        content: '這是我的簡歷頭像:',
        ctime: new Date().toLocaleString()
      },
      {
        direction: 2,
        id: 4,
        type: 2,
        content: './src/assets/wyz.jpg',
        ctime: new Date().toLocaleString()
      },
      {
        direction: 1,
        id: 5,
        type: 1,
        content: '你開心就好。[微笑]',
        ctime: new Date().toLocaleString()
      }]
    }
  },
  components:{wxChat},

  methods:{

    //向上滾動加載數(shù)據(jù)
    getUpperData(){
      var me = this;
      
      // 這里為模擬異步加載數(shù)據(jù)
      // 實際上你可能要這么寫:
      // return axios.get('xxx').then(function(result){
      //     return result;  //result的格式需要類似下面resolve里面的數(shù)組
      // })
      return new Promise(function(resolve){
        setTimeout(function(){
           //模擬加載完畢
          if(me.upperTimes>3){
            return resolve([]);
          }
          
          //加載數(shù)據(jù)
          resolve([{
              direction: 2,
              id: me.upperId-1,
              type: 1,
              content: '向上滾動加載第 ' + me.upperTimes +' 條!',
              ctime: new Date().toLocaleString()
            },
            {
              direction: 1,
              id: me.upperId-2,
              type: 1,
              content: '向上滾動加載第 ' + me.upperTimes +' 條!',
              ctime: new Date().toLocaleString()
            }]
      
          )
        }, 1000);
        me.upperId= me.upperId+2;
        me.upperTimes++;
      })
    },

    getUnderData(){
      var me = this;

      //意義同getUpperData()
      return new Promise(function(resolve){
        setTimeout(function(){
          //模擬加載完畢
          if(me.underTimes>3){
            return resolve([]);
          }
          
          //加載數(shù)據(jù)
          resolve(
            [{
              direction: 1,
              id: me.underId+1,
              type: 1,
              content: '向下滾動加載第 ' + me.underTimes +' 條!',
              ctime: new Date().toLocaleString()
            },
            {
              direction: 2,
              id: me.underId+2,
              type: 1,
              content: '向下滾動加載第 ' + me.underTimes +' 條!',
              ctime: new Date().toLocaleString()
            }]
          )
        }, 1000);

        me.underId = me.underId+2;
        me.underTimes++;
      })
    }

  }
}
</script>

<style>
*{
  margin: 0;
  padding: 0;
}
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

h1, h2 {
  font-weight: normal;
}

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

li {
  display: inline-block;
}

</style>

歡迎 start:
https://github.com/doterlin/vue-wxChat

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容