本文实例为大家分享了Vue实现聊天界面展示的具体代码,供大家参考,具体内容如下
1.功能需求
根据索引选择跟不同的人进行聊天
2.代码展示
mock.js:
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:\'/ChatDetail\', 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=\"scss\" 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\"> <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, 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, 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\"> <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, 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, 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, 212, 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, 228, 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, 228, 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, 228, 116) transparent transparent; } } } </style>
3.目录结构
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
© 版权声明
THE END
暂无评论内容