<template>
<div class="content">
<div class="message_content">
<div class="message_title">
<span>消息区</span>
</div>
<!-- 消息区 -->
<div class="message_area" ref="chatWindow">
<div
class="message_item"
:style="{
justifyContent: item.name == '张三' ? 'flex-end' : 'flex-start',
}"
v-for="(item, index) in messageList"
:key="index"
>
<div class="avator" v-if="item.name != '张三'">
<img src="xxx/avator.png" alt="" />
</div>
<div class="">
<div class="name">{{ item.name }}</div>
<div
class="message"
:class="{
message_right: item.name == '张三',
message_left: item.name != '张三',
}"
>
{{ item.content }}
</div>
</div>
<div class="avator" v-if="item.name == '张三'">
<img src="xxx/avator.png" alt="" />
</div>
</div>
</div>
<div class="message_input">
<el-input
type="textarea"
v-model="textarea"
autofocus
:autosize="{ minRows: 7, maxRows: 7 }"
resize="none"
@keyup.enter="keyDown($event)"
>
</el-input>
<div
style="
width: 100%;
display: flex;
align-items: center;
justify-content: flex-end;
height: 60px;
"
>
<el-button @click="send">发送</el-button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
textarea: "",
messageList: [
{
name: "张三",
content: "你好",
},
{
name: "李四",
content: "你好",
},
{
name: "王五",
content: "你好",
},
{
name: "赵六",
content: "你好",
},
{
name: "张三",
content: "你好",
},
],
};
},
watch: {},
mounted() {
window.addEventListener("keydown", this.keyDowns);
},
methods: {
/* 回车发送消息 */
keyDowns(e) {
if (e.key == "Enter") {
this.send();
e.preventDefault(); // 去掉默认的换行
}
},
/* 点击发送消息 */
send() {
if (!this.textarea) return;
this.messageList.push({
name: "张三",
content: this.textarea,
time: this.formatDate(new Date()),
});
console.log(this.messageList);
this.textarea = "";
this.scrollToBottom();
},
/* 滚动到底部 永远保持显示最新消息 */
scrollToBottom() {
// 使用setTimeout确保DOM更新完成
setTimeout(() => {
this.$refs.chatWindow.scrollTop = this.$refs.chatWindow.scrollHeight;
}, 0);
},
/* 时间格式化 */
formatDate(date) {
const d = new Date(date);
let month = "" + (d.getMonth() + 1);
let day = "" + d.getDate();
let hour = "" + d.getHours();
let minute = "" + d.getMinutes();
let second = "" + d.getSeconds();
let year = d.getFullYear();
if (month.length < 2) month = "0" + month;
if (day.length < 2) day = "0" + day;
if (hour.length < 2) hour = "0" + hour;
if (minute.length < 2) minute = "0" + minute;
if (second.length < 2) second = "0" + second;
return (
[year, month, day].join("-") + " " + [hour, minute, second].join(":")
);
},
},
beforeDestroy() {
window.addEventListener("keydown", this.keyDowns);
},
};
</script>
<style lang="scss" scoped>
::v-deep .el-textarea {
height: calc(100% - 60px);
}
::v-deep .el-textarea__inner {
height: 105px !important;
color: #fff;
min-height: 105px !important;
background-color: transparent;
border: 0;
}
::v-deep ::-webkit-scrollbar {
background-color: transparent !important;
}
.message_left {
border-top-right-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
.message_right {
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
.content {
border: 2px solid #26c4d1;
border-radius: 5px;
background-color: rgba(13, 26, 42, 0.5);
box-shadow: 0 0 10px 1px #26c4d1;
margin-right: 10px;
width: 400px;
height: 800px;
display: flex;
.message_content {
width: 38%;
}
.message_content {
width: 400px;
height: 100%;
border-radius: 5px;
box-shadow: 0 0 5px 1px #89d8f0;
background-color: rgba(66, 86, 94, 0.2);
.message_title {
height: 50px;
line-height: 50px;
color: #50d7d3;
text-align: center;
background-color: #174670;
}
.message_area {
width: 100%;
height: calc(100% - 223px);
overflow-y: auto;
.message_item {
display: flex;
justify-content: flex-end;
margin: 5px 0;
.avator {
width: 40px;
height: 40px;
border-radius: 50%;
margin-right: 10px;
margin-left: 10px;
img {
display: block;
width: 100%;
height: 100%;
}
}
.name {
color: #67798e;
}
.message {
color: #71acbd;
padding: 5px;
background-color: #1f3144;
border: 1px solid #71acbd;
}
}
}
.message_input {
// border: 1px solid #3e5a77;
margin: 5px auto 0 auto;
width: 96%;
height: 165px;
border-radius: 5px;
box-shadow: 0 0 5px 1px #89d8f0;
background-color: rgba(97, 156, 180, 0.2);
}
}
}
::v-deep .el-button {
color: #fff;
border-radius: 5px;
border: 1px solid #43a0a8;
background-image: linear-gradient(to bottom, #15263b, #238298);
margin-right: 10px;
}
</style>
(一)vue聊天功能界面
于 2024-08-27 11:37:50 首次发布