1. 程式人生 > 程式設計 >Vue實現聊天介面

Vue實現聊天介面

本文例項為大家分享了實現聊天介面展示的具體程式碼,供大家參考,具體內容如下

1.功能需求

根據索引選擇跟不同的人進行聊天

Vue實現聊天介面

Vue實現聊天介面

2.程式碼展示

mock.:

import Mock from 'mockjs'
Mock.mock("/chatchild",{
    'result':[
        {
            id:"001",imgurl:"/static/image/10.jpg",name:"XKDK",date:"09:23",words:"哈哈,好噠"
        },// ... ...
    ]
});
export default Mock

userinfo.js:

let usermsg={
    id:"122",imgurl:"/static/image/8.jpg",words:"是的!",data:{
        id:"1529",imgurl:"/static/image/7.jpg",name:"易安居士",words:[
            {info:"在嗎?"},{info:"不在"},{info:"你把草稿交了沒有"},{info:"我今天中午吃完飯   就一直看劇了"},{info:"我發現我真的是宅女"},{info:"哈哈哈"},           {info:"有空找你約頓飯"},{info:"嗯嗯"},{info:"反正影響不大"}
        ]
    }
}
export default usermsg

index.js:

import Vue from 'vue'
import Router from 'vue-router'
import Chat from '../components/Chat.vue'
import ChatDetail from '../components/Pages/ChatDetail.vue'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/Chat ',component: Chat 
    },{
      path:'/ChatDetaildlBMLEGsI
',component:ChatDetail } ] }) // 解決路由報錯的程式碼 const originalPush = Router.prototype.push Router.prototype.push = function push(location) { return originalPush.call(this,location).catch(err => err) }

Chat.vue:

<template>
  <div id="chat">
    <Bottom />
    <Header :name="msg" />
    <div class="chat_alluser">
      <div ref="chatuser" @click="checkChild(index)" class="chatuser" v-for="(item,index) in chat" :key="index">
        <ChatChild :imgsrc="item.imgurl" :nickname="item.name" :time="item.date" :word="item.words" />
      </div>
    </div>
  </div>
</template>

<script>
import Bottom from "../components/Menu/Bottom";
import Header from "../components/Menu/Header";
import ChatChild from "../components/Pages/ChatChild";
export default {
  name: "Chat",components: {
    Bottom: Bottom,Header: Header,ChatChild: ChatChild
  },data() {
    return {
      msg: "微信",chat: null,name: null
    };
  },mounted() {
    this.$axios.get("/chatchild").then(res => {
      this.chat = res.data.result;
    });
  },methods: {
    checkChild(index) {
      this.$refs.chatuser[index].style.backgroundColor = "rgb(240,240,240)";
      // 動態dom元素渲染完成之後,跳轉到另一個介面(ChatDetail)
      // 獲取動態name
      let username = this.chat[index].name;
      this.$nextTick(() => {
        this.$router.push({
          path: "/ChatDetail",query: { name: username }
        });
      });
    }
  }
};
</script>

<style lang="s" scope>
#chat {
  width: 100%;
  .chat_alluser {
    margin-bottom: 7.5rem;
    .chatuser {
      position: relative;
      top: 3.5rem;
      padding: 0.3rem 0;
    }
  }
}
</style>

父元件使用子元件裡的屬性和方法:
在父元件中的子元件上定義ref屬性,通過 this.$ refs.name.屬性或this.$refs.name.方法

ChatChild.vue:

<template>
  <div id="chatchild">
    &dlBMLEGsIlt;div class="photo">
      <img :src="imgsrc" alt />
    </div>
    <div class="content">
      <div>
          <span class="content_nickname">{{nickname}}</span>
          <span class="content_time">{{time}}</span>
      </div>
      <span class="content_word">{{word}}</span>
    </div>
  </div>
</template>

<script>
export default {
  name: "ChatChild",props:{
    'imgsrc':String,'nickname':String,'time':String,'word':String
  }
};
</script>

<style lang="scss" scope>
#chatchild {
  width: 100%;
  height: 5rem;
  display: flex;
  flex-direction: row;
  box-sizing: border-box;
  .photo {
    flex: 1;
    height: 5rem;
    img{
        object-fit: cover;
        width: 4rem;
        height: 4rem;
        border-radius: 5px;
        display: block;
        margin: 0 auto;
        margin-top: 0.5rem;
        margin-left: 1rem;
    }
  }
  .content {
    flex: 4;
    height: 5rem;
    border-bottom: 0.5px solid rgb(240,240);
    padding-left: 0.5rem;
    padding-top: 0.5rem;
    box-sizing: border-box;
    div{
      .content_nickname{
        display: inline-block;
        font-size: 1.1rem;
        margin-top: 0.3rem;
      }
      .content_time{
        float: right;
        margin-right: 1rem;
        color: rgb(209,206,206);
        font-size: 0.8rem;
      }
    }
    .content_word{
      color: rgb(209,206);
      font-size: 0.8rem;
      display: block;
      margin-top: 0.5rem;
    }
  }
}
</style>

ChatDetail.vue:

<template>
  <div id="chatdetail">
    <div class="chattop">
      <div @click="goback" class="chattop_back">
        <icon-svg icon-class="houtui_shangyibu_zuojiantou_shangyiye" />
      </div>
      <div class="chattop_name">{{name}}</div>
      <div class="chattop_more"&gdlBMLEGsIt;
        <icon-svg icon-class="gengduo" />
      </div>
    </div>
    <div class="chatcontent">
      <ChatMsg ref="chatmsg" />
    </div>
    <div class="chatfooter">
      <div @click="changeSound">
        <icon-svg :icon-class="issound" />
      </div>
      <div>
        <input ref="sendcontent" @keypress="sendmsg" :type="istype" :value="isvalue" />
      </div>
      <div>
        <icon-svg icon-class="biaoqing" />
      </div>
      <div>
        <icon-svg icon-class="del" />
      </div>
    </div>
  </div>
</template>

<script>
import ChatMsg from "./ChatMsg";
export default {
  name: "ChatDetail",data() {
    return {
      name: null,issound: "xiaoxitongzhi",istype: "text",isvalue: "",isshow: false,tomsg: "",msgchild: null
    };
  },components: {
    ChatMsg: ChatMsg
  },mounted() {
    this.name = this.$route.query.name;
    this.msgchild = this.$refs.chatmsg;
  },methods: {
    // 進行返回操作
    goback() {
      this.$router.go(-1);
    },// 切換input的型別
    changeSound() {
      // 在data中定義一個變數isshow:false,利用this.isshow與!this.isshow進行切換
      if (!this.isshow) {
        this.isshow = true;
        this.issound = "yuyin";
        this.istype = "button";
        this.isvalue = "按住 說話";
      } else {
        this.isshow = false;
        this.issound = "xiaoxitongzhi";
        this.istype = "text";
        this.isvalue = "";
      }
    },// 傳送訊息
    sendmsg(e) {
      // 1、用ref定義輸入回覆內容的input文字框,定義sendcontent變數接收其value值(輸入的內容)
      let sendcontent = this.$refs.sendcontent.value;
      if (e.keyCode === 13 && sendcontent.split(" ").join("").length !== 0) {
        // 2、將ChatDetail(父)元件中的sendcontent(文字框輸入的值)先用tomsg接收
        this.tomsg = sendcontent;
        // 3、用ref定義ChatMsg(子)元件,並在mounted中使用$refs獲取,即this.msgchild
        // 4、調子元件裡的方法,並將tomsg傳到ChatMsg(子)元件(具體的聊天內容)中
        this.msgchild.saveMsg(this.tomsg);
        // 5、傳送完一條資訊之後,需清空文字框
        this.$refs.sendcontent.value = "";
        // 回車時,呼叫子元件的隨機訊息的方法
        this.msgchild.randomMsg();
      }
    }
  }
};
</script>

<style lang="scss" scope>
#chatdetail {
  position: relative;
  background-color: rgb(238,212,238);
  .chattop {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 10;
    width: 100%;
    height: 3.5rem;
    line-height: 3.5rem;
    background-color: rgb(240,240) !important;
    display: flex;
    flex-direction: row;
    .chattop_back {
      flex: 1;
      margin-left: 1rem;
    }
    .chattop_name {
      flex: 20;
      text-align: center;
    }
    .chattop_more {
      flex: 1;
      margin-right: 1rem;
    }
  }
  .chatcontent {
    width: 100%;
    height: 100%;
  }
  .chatfooter {
    position: fixed;
    left: 0;
    bottom: 0;
    z-index: 10;
    width: 100%;
    height: 3.5rem;
    line-height: 3.5rem;
    text-align: center;
    background-color: rgb(240,240) !important;
    display: flex;
    flex-direction: row;
    div:nth-child(1),div:nth-child(3),div:nth-child(4) {
      flex: 1;
      svg {
        font-size: 1.5rem;
        margin-top: 0.9rem;
      }
    }
    div:nth-child(2) {
      flex: 5;
      input {
        width: 100%;
        height: 2.5rem;
        outline: none;
        padding-left: 0.5rem;
        box-sizing: border-box;
        height: 2.5rem;
        margin-top: 0.5rem;
        border-style: none;
        font-size: 0.9rem;
        border-radius: 4px;
        background-color: #fff;
        color: #000;
      }
    }
  }
}
</style>

ChatMsg.vue:

<template>
  <div id="chatmsg" ref="msg">
    <!-- 動態建立 -->
    <div v-for="(item,index) in lists" :key="index">
      <div v-if="item.id==122" class="user">
        <div v-scroll>
          <img :src="item.face" alt />
          <div class="bubble">
            <span>{{item.word}}</span>
          </div>
        </div>
      </div>
      <div v-if="item.id==1529" class="touser">
        <div v-scroll>
          <img :src="item.face" alt />
          <div class="tobubble">
            <span>{{item.word}}</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import userinfo from "./userinfo";
export default {
  name: "ChatMsg",data() {
    return {
      userimg: "",lists: []
    };
  },mounted() {
    this.userid = userinfo.id;
    this.userimg = userinfo.imgurl;
  },// vue自動滾動到底部
  directives: {
    scroll: {
      inserted(el) {
        el.scrollIntoView();
      }
    }
  },methods: {
    saveMsg(tomsg) {
      this.lists.push({
        id: this.userid,face: this.userimg,word: tomsg
      });
    },randomMsg() {
      let touserdata = userinfo.data;
      this.lists.push({
        id: touserdata.id,face: touserdata.imgurl,word:
          touserdata.words[Math.floor(Math.random() * touserdata.words.length)]
            .info
      });
    }
  }
};
</script>

<style lang="scss" scope>
#chatmsg {
  position: relative;
  top: 3.5rem;
  width: 100%;
  min-height: 44rem;
  background-color: rgb(238,238);
  margin-bottom: 3.5rem;
  overflow-x: hidden;
  overflow-y: auto;
  .user {
    position: relative;
    width: 100%;
    overflow: hidden;
    margin: 0.8rem 0;
    img {
      object-fit: cover;
      width: 3rem;
      height: 3rem;
      border-radius: 3px;
      float: right;
      margin-right: 1rem;
    }
    .bubble {
      position: relative;
      float: right;
      margin-right: 1rem;
      padding: 0.8rem;
      box-sizing: border-box;
      border-radius: 3px;
      max-width: 65%;
      background-color: rgb(116,228,116);
      span {
        height: 1.25rem;
        line-height: 1.25rem;
      }
    }
    .bubble::after {
      position: absolute;
      right: -1.3rem;
      top: 0.8rem;
      content: "";
      width: 0;
      height: 0;
      border: 0.7rem solid;
      border-color: transparent transparent transparent rgb(116,116);
    }
  }
  .touser {
    position: relative;
    width: 100%;
    overflow: hidden;
    margin: 0.8rem 0;
    img {
      object-fit: cover;
      width: 3rem;
      height: 3rem;
      border-radius: 3px;
      float: left;
      margin-left: 1rem;
    }
    .tobubble {
      position: relative;
      float: left;
      margin-left: 1rem;
      padding: 0 0.7rem;
      box-sizing: border-box;
      border-radius: 3px;
      max-width: 65%;
      background-color: rgb(116,116);
      line-height: 3rem;
    }
    .tobubble::after {
      position: absolute;
      left: -1.3rem;
      top: 0.8rem;
      content: "";
      width: 0;
      height: 0;
      border: 0.7rem solid;
      border-color: transparent rgb(116,116) transparent transparent;
    }
  }
}
</style>

3.目錄結構

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。