Vue实现聊天界面
本文实例为大家分享了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.目录结构
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
以上是 Vue实现聊天界面 的全部内容, 来源链接: utcz.com/p/239363.html