Vue實現聊天介面
阿新 • • 發佈:2021-06-29
本文例項為大家分享了實現聊天介面展示的具體程式碼,供大家參考,具體內容如下
1.功能需求
根據索引選擇跟不同的人進行聊天
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.目錄結構
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。