363 lines
10 KiB
Vue
363 lines
10 KiB
Vue
<template>
|
||
<div class="pageCantainer">
|
||
<div class="pageContent">
|
||
<div class="chatSide">
|
||
<div class="sideContent">
|
||
<div plain="true" class="addBtn" @click="createNewChat">新建聊天</div>
|
||
<div class="chatList">
|
||
<div class="listItem" v-for="(item,$index) in listData" :key="item.id" @click="listItemClick(item.id)">
|
||
<el-input v-if="item.isEdit" v-model="item.title" style="width: 160px;"></el-input>
|
||
<div class="listItemTitle" v-else>{{ item.title }}</div>
|
||
<el-icon v-if="item.isEdit" class="listItemIcons" :size="15" @click="saveListItem(item.id,$index)"><el-icon-finished/></el-icon>
|
||
<el-icon v-else class="listItemIcons" :size="15" @click="editListItem(item.id,$index)"><el-icon-edit/></el-icon>
|
||
<el-popconfirm title="确定删除吗?" @confirm="deleteListItem(item.id,$index)">
|
||
<template #reference>
|
||
<el-icon v-if="!item.isEdit" :size="15" class="listItemIcons"><el-icon-delete/></el-icon>
|
||
</template>
|
||
</el-popconfirm>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="mainChat">
|
||
<el-container>
|
||
<el-main class="chatItemContainer">
|
||
<div v-for="item in chatData" :key="item.id">
|
||
<div class="chatItem" :class="[item.chat_type=='myself'?'layout_right':'layout_left']">
|
||
<div class="chatItem_text">
|
||
<span class="datatime">{{ item.chat_time }}</span>
|
||
<div class="chat_text">{{ item.chat_text }}</div>
|
||
</div>
|
||
<div class="user_icons"></div>
|
||
</div>
|
||
</div>
|
||
</el-main>
|
||
<el-footer class="footerWrap">
|
||
<div class="footerContent">
|
||
<div class="footerInput">
|
||
<el-input v-model="newQuestion" class="search_input" placeholder="来说点什么吧..."></el-input>
|
||
</div>
|
||
<el-button @click="sendQuestion" icon="el-icon-promotion" size="success"></el-button>
|
||
</div>
|
||
</el-footer>
|
||
</el-container>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<script>
|
||
export default {
|
||
name: "testx",
|
||
components: {},
|
||
data() {
|
||
return {
|
||
userName: "",
|
||
newQuestion: "",
|
||
currentItem:{},
|
||
listData:[{id:1,title:'前端有哪些性能优化?',isEdit:false}],
|
||
originData:[
|
||
{
|
||
id:1,
|
||
title:'前端有哪些性能优化?',
|
||
isEdit:false,
|
||
data:[
|
||
{chat_text:'前端有哪些性能优化?',chat_time:'2022-08-18 10:00:00',chat_type:'myself'},
|
||
{chat_text:'1. 图片优化使用适当格式(例如:JPEG, PNG, WebP)。压缩图片文件,减少文件大小。使用响应式图片(srcset)来适配不同分辨率的设备。2. 懒加载(Lazy Loading)对图片、视频和其他资源进行懒加载,仅在需要时才加载。使用 IntersectionObserver 或 loading="lazy" 属性来实现。3. 代码拆分(Code Splitting)将 JavaScript 拆分成更小的模块,按需加载,提高初始加载速度。使用 Webpack 或其他打包工具的代码分割功能。4. 资源缓存使用浏览器缓存(Cache-Control)来减少重复请求。使用 Service Workers 提供离线支持和缓存管理5. 减少 HTTP 请求合并 CSS 和 JavaScript 文件,减少请求次数。使用字体图标代替多个图片图标。',chat_time:'2022-08-18 10:00:00',chat_type:'serve'}
|
||
]
|
||
},
|
||
],
|
||
chatData: [
|
||
{chat_text:'前端有哪些性能优化?',chat_time:'2022-08-18 10:00:00',chat_type:'myself'},
|
||
{chat_text:'1. 图片优化使用适当格式(例如:JPEG, PNG, WebP)。压缩图片文件,减少文件大小。使用响应式图片(srcset)来适配不同分辨率的设备。2. 懒加载(Lazy Loading)对图片、视频和其他资源进行懒加载,仅在需要时才加载。使用 IntersectionObserver 或 loading="lazy" 属性来实现。3. 代码拆分(Code Splitting)将 JavaScript 拆分成更小的模块,按需加载,提高初始加载速度。使用 Webpack 或其他打包工具的代码分割功能。4. 资源缓存使用浏览器缓存(Cache-Control)来减少重复请求。使用 Service Workers 提供离线支持和缓存管理5. 减少 HTTP 请求合并 CSS 和 JavaScript 文件,减少请求次数。使用字体图标代替多个图片图标。',chat_time:'2022-08-18 10:00:00',chat_type:'serve'},
|
||
],
|
||
};
|
||
},
|
||
watch: {
|
||
nodes: {
|
||
listData(val) {
|
||
console.log(val);
|
||
this.$nextTick(() => {
|
||
this.nodeAddClick();
|
||
})
|
||
},
|
||
deep: true,
|
||
},
|
||
},
|
||
mounted() {
|
||
var userInfo = this.$TOOL.data.get("USER_INFO");
|
||
this.userName = userInfo.username;
|
||
//给每个记录添加触发函数
|
||
this.nodeAddClick();
|
||
//获取历史聊天列表放到listData;
|
||
this.getListData();
|
||
},
|
||
methods: {
|
||
//获取历史聊天列表
|
||
getListData(){
|
||
//将列表第一个放到谈话框chatData = this.listData[0].data;
|
||
},
|
||
nodeAddClick(){
|
||
let items = document.querySelectorAll('.listItem');
|
||
items.forEach(function(item) {
|
||
item.addEventListener('click', function() {
|
||
items.forEach(function(el) {
|
||
el.classList.remove('active');
|
||
});
|
||
item.classList.add('active');
|
||
});
|
||
})
|
||
},
|
||
//新建聊天记录
|
||
createNewChat(){
|
||
let that = this;
|
||
let obj = {title:'New Chat',id:null,isEdit:false};
|
||
that.currentItem = obj;
|
||
console.log('that.currentItem',that.currentItem);
|
||
that.listData.unshift(obj);
|
||
that.chatData = [];
|
||
that.$nextTick(()=>{
|
||
that.nodeAddClick();
|
||
let items = document.querySelectorAll('.listItem');
|
||
items.forEach(function(el) {
|
||
el.classList.remove('active');
|
||
});
|
||
items[0].classList.add('active')
|
||
})
|
||
},
|
||
//点击聊天记录,展示聊天内容
|
||
listItemClick(id){
|
||
let that = this;
|
||
that.chatData = [];
|
||
that.originData.forEach((item)=>{
|
||
if(item.id == id){
|
||
that.chatData = item.data;
|
||
that.currentItem = item;
|
||
console.log('that.currentItem',that.currentItem);
|
||
}
|
||
})
|
||
},
|
||
//删除聊天记录
|
||
deleteListItem(id,index){
|
||
|
||
},
|
||
//编辑聊天记录title
|
||
editListItem(id,index){
|
||
this.listData[index].isEdit = true;
|
||
},
|
||
//聊天记录保存
|
||
saveListItem(id,index){
|
||
this.listData[index].isEdit = false;
|
||
// this.$API
|
||
},
|
||
sendQuestion(){
|
||
let that = this;
|
||
let date = new Date();
|
||
let id = date.getTime();
|
||
console.log('that.currentItem',that.currentItem);
|
||
if(that.currentItem.id!==null){
|
||
that.chatData.push({chat_text:this.newQuestion,chat_time:date,chat_type:'myself'});
|
||
that.newQuestion = '';
|
||
that.$nextTick(()=>{
|
||
//接口请求发送记录Id和输入框里的问题
|
||
})
|
||
}else{
|
||
//如果该聊天记录没有id 则新建一条新聊天记录,并且将当前聊天记录放到新记录里
|
||
}
|
||
|
||
},
|
||
|
||
//删除问题
|
||
},
|
||
};
|
||
</script>
|
||
<style scoped>
|
||
.pageCantainer{
|
||
padding:0;
|
||
width: 99%;
|
||
height: 99%;
|
||
border-radius: 0.375rem;
|
||
margin: 0.5vh auto 0;
|
||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0 ,.1), 0 2px 4px -2px rgba(0, 0, 0 ,.1);
|
||
}
|
||
.pageContent{
|
||
width: 100%;
|
||
height: 100%;
|
||
position: relative;
|
||
background: #fff;
|
||
border-radius: 6px;
|
||
}
|
||
.chatSide{
|
||
max-width: 260px;
|
||
width: 260px;
|
||
border-right: 1px solid rgb(229, 231, 235);
|
||
box-sizing: border-box;
|
||
height: 100%;
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0;
|
||
z-index: 10;
|
||
}
|
||
.sideContent{
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-height: 0;
|
||
height: 100%;
|
||
/* flex:1 1 0%; */
|
||
}
|
||
.addBtn{
|
||
margin: 1rem;
|
||
border: 1px dotted #dddddd;
|
||
height: 35px;
|
||
line-height: 35px;
|
||
text-align: center;
|
||
cursor: pointer;
|
||
}
|
||
.addBtn:hover{
|
||
color: #18a058;
|
||
border: 1px dotted #18a058;
|
||
}
|
||
.chatList{
|
||
padding: 0 1rem 2rem 1rem;
|
||
flex: 1;
|
||
min-height: 0px;
|
||
overflow-y: scroll;
|
||
box-sizing: border-box;
|
||
}
|
||
.listItem{
|
||
overflow: hidden;
|
||
position: relative;
|
||
z-index: auto;
|
||
height: 45px;
|
||
line-height: 45px;
|
||
width: 100%;
|
||
display :flex;
|
||
padding: 0 1rem;
|
||
border-radius: 6px;
|
||
box-sizing: border-box;
|
||
color :rgb(51, 54, 57);
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
cursor: pointer;
|
||
margin: 8px 0;
|
||
border :1px solid rgb(229, 231, 235);
|
||
}
|
||
.listItem.active{
|
||
color: rgb(75, 158, 95);
|
||
border-color: rgb(75, 158, 95);
|
||
background-color :rgb(245, 245, 245)
|
||
}
|
||
.listItem>.listItemIcons{
|
||
display: none;
|
||
}
|
||
.listItem.active>.listItemIcons{
|
||
display: block;
|
||
}
|
||
.listItemTitle{
|
||
width: 160px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
}
|
||
.mainChat{
|
||
padding-left: 260px;height: 100%;box-sizing: border-box;position: relative;z-index: auto;
|
||
}
|
||
|
||
|
||
|
||
.icons {
|
||
background-color: white;
|
||
z-index: 99;
|
||
position: absolute;
|
||
font-size: 20px;
|
||
border-radius: 50%;
|
||
border: 1px solid lightgray;
|
||
padding: 0px 5px;
|
||
box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
|
||
color: gray;
|
||
}
|
||
|
||
.icons_display {
|
||
top: 48vh;
|
||
right: -15px;
|
||
}
|
||
|
||
.icons_hideen {
|
||
top: 48vh;
|
||
left: 10px;
|
||
display: none;
|
||
}
|
||
.user_icons {
|
||
width: 50px;
|
||
height: 50px;
|
||
background: linear-gradient(-135deg, #0000cc, #009dff);
|
||
border: 1px solid lightblue;
|
||
border-radius: 50%;
|
||
}
|
||
.btn{
|
||
border:none;
|
||
padding:10px 15px;
|
||
background-color: #18a058;
|
||
border-radius: 1px;
|
||
color:white;
|
||
}
|
||
.search_input{
|
||
width: 100%;
|
||
padding:0.5rem 1rem;
|
||
/* border:1px solid lightgray; */
|
||
}
|
||
.chatItemContainer{
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
.chatItem{
|
||
display: flex;
|
||
justify-content: flex-end; /* 对齐到容器的右侧 */
|
||
}
|
||
.chatItem.layout_left{
|
||
flex-direction: row-reverse; /* 从右到左排列 */
|
||
}
|
||
|
||
.chatItem_text{
|
||
display: flex;
|
||
flex-direction: column;
|
||
max-width: 80%;
|
||
}
|
||
.datatime{
|
||
margin: 5px;
|
||
display: inline-block;
|
||
color:rgb(180, 187, 196);
|
||
}
|
||
.layout_right .datatime{
|
||
text-align: right;
|
||
}
|
||
.layout_right>.chatItem_text>.chat_text{
|
||
padding:10px 20px;
|
||
border-radius: 10px;
|
||
background-color: rgb(210, 249, 209);
|
||
opacity: 0.8;
|
||
}
|
||
.layout_left>.chatItem_text>.chat_text{
|
||
padding:10px 20px;
|
||
border-radius: 10px;
|
||
background-color: rgb(244, 246, 248);
|
||
opacity: 0.8;
|
||
}
|
||
.footerWrap{
|
||
padding: 1rem;
|
||
height: 5rem;
|
||
text-align: left;
|
||
border-top: 1px solid rgb(229, 231, 235);
|
||
}
|
||
.footerContent{
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
.footerInput{
|
||
width: 100%;
|
||
height:100%;
|
||
padding: 0 0.5rem;
|
||
}
|
||
</style> |