开始
构建data数据
先来构建data数据
isme是否是好友发的,false 表示是好友发的、
list: [{
isme: false,
userpic: "../../static/demo/userpic/11.jpg",
type: "text",
data: "哈哈哈",
time: "1555146412"
}]
最上面加一个时间
<view class="user-chat-time u-f-ajc">11:10</view>
ajc垂直水平居中。
上下50内间距,左右为0
时间戳的转换
https://www.matools.com/timestamp
这里的时间戳是php生成的 10位的
js生成的话 后面有3个000
这里我们的后端也是PHP的所以这里还是用10位的
list: [
{
isme: false,
userpic: "../../static/demo/userpic/11.jpg",
type: "text",
data: "哈哈哈",
time: "1555146412"
},
{
isme: true,
userpic: "../../static/demo/userpic/10.jpg",
type: "img",
data: "../../static/demo/3.jpg",
time: "1555146414",
}
]
循环数据
外层用block
时间先换成时间戳
左边是好友发过来的,右边是自己发过来的
取反代表 好友发送的消息,不是自己发的
如果是文本就显示文本信息。
如果是图片 就显示图片
<block v-for="(item,index) in list" :key="index">
<view class="user-chat-time u-f-ajc">{{item.time}}</view>
<view class="user-chat-list u-f user-chat-me">
<image v-if="!item.isme" :src="item.userpic" mode="widthFix"
lazy-load="true"></image>
<view class="user-chat-list-body">
<text v-if="item.type=='text'">{{item.data}}</text>
<image v-if="item.type=='img'" :src="item.data" mode="widthFix" lazy-load="true"></image>
</view>
<image v-if="item.isme" :src="item.userpic" mode="widthFix" lazy-load="true"></image>
</view>
</block>
这是因为这个样式引起的
如果是isme是true的时候才添加user-chat-me的class属性
先把时间栏 暂时屏蔽
<view class="user-chat-list u-f" :class="{'user-chat-me':item.isme}">
左边聊天框的小箭头,位置不合适,自己又调整了一下,主要是left
left: -50upx;
增加内边距。上下20 左右为0
.user-chat-list {
padding: 20upx 0;
}
处理时间戳
时间转换的工具库,这个是事先写好的
判断时间戳是否小于13位,就乘以1000
当天,隔天,隔年。 当前时间减去传过来的时间戳 判断 当天。隔天 和隔年
使用工具类
测试数据。在onLoad的方法里面测试 转换前和转换后的时间戳数据。
今天的时间
今天的时间就显示下午
所以在这里直接调用方法是不支持的
假设这里就是从服务器上获取到的数据
一定要在页面加载的时候调用
循环拿到的数据,单独给时间戳字段进行转换。
相当于增加一个字段属性,把转换后的属性值复制给这个新的字段。
getData() {
// 从服务器获取到的数据
let arr = [{
isme: false,
userpic: "../../static/demo/userpic/11.jpg",
type: "text",
data: "哈哈哈",
time: "1555146412"
},
{
isme: true,
userpic: "../../static/demo/userpic/10.jpg",
type: "img",
data: "../../static/demo/3.jpg",
time: "1555146414",
},
];
for (let i = 0; i < arr.length; i++) {
arr[i].gstime = time.gettime.getChatTime(arr[i].time, i > 0 ? arr[i - 1].time : 0);
}
this.list = arr;
},
这样就是转换后的数据了
改成相差不久的时间
如果时间都在某个时间段之内。 只会显示一个。
两个信息如果相差300秒 不会显示时间的。
传入上一条信息的时间
第0条的情况。
只会显示第一条。
超过300秒
如果格式的时间没有的话, 就隐藏当前view这一行。这样他们之间的距离就会减少一点边距。
<view v-if="item.gstime" class="user-chat-time u-f-ajc">{{item.gstime}}</view>
封装组件
封装list组件
剪切走
<view v-if="item.gstime" class="user-chat-time u-f-ajc">{{item.gstime}}</view>
<view class="user-chat-list u-f" :class="{'user-chat-me':item.isme}">
<image v-if="!item.isme" :src="item.userpic" mode="widthFix" lazy-load="true"></image>
<view class="user-chat-list-body">
<text v-if="item.type=='text'">{{item.data}}</text>
<image v-if="item.type=='img'" :src="item.data" mode="widthFix" lazy-load="true"></image>
</view>
<image v-if="item.isme" :src="item.userpic" mode="widthFix" lazy-load="true"></image>
</view>
最外层套一个view
全部的css也剪切过来
传入的属性
<script>
export default{
props:{
item: Object,
index: Number
}
}
</script>
引入组件
import userChatList from '@/components/user-list/user-chat-list.vue';
<user-chat-list :item="item" :index="index"></user-chat-list>
本节代码
user-chat-list组件
<template>
<view>
<view v-if="item.gstime" class="user-chat-time u-f-ajc">{{item.gstime}}</view>
<view class="user-chat-list u-f" :class="{'user-chat-me':item.isme}">
<image v-if="!item.isme" :src="item.userpic" mode="widthFix" lazy-load="true"></image>
<view class="user-chat-list-body">
<text v-if="item.type=='text'">{{item.data}}</text>
<image v-if="item.type=='img'" :src="item.data" mode="widthFix" lazy-load="true"></image>
</view>
<image v-if="item.isme" :src="item.userpic" mode="widthFix" lazy-load="true"></image>
</view>
</view>
</template>
<script>
export default{
props:{
item: Object,
index: Number
}
}
</script>
<style scoped>
.user-chat-list {
padding: 20upx 0;
}
.user-chat-list>image {
width: 100upx;
height: 100upx;
border-radius: 100%;
flex-shrink: 0;
}
/* 聊天背景 */
.user-chat-list-body {
position: relative;
background: #f4f4f4;
padding: 25upx;
margin-left: 20upx;
border-radius: 20upx;
margin-right: 100upx;
}
.user-chat-list-body:after {
position: absolute;
left: -50upx;
right: 0;
top: 20upx;
content: '';
width: 0;
height: 0;
border: 16px solid #F4F4F4;
border-color: transparent #F4F4F4 transparent transparent;
}
.user-chat-me {
justify-content: flex-end;
}
.user-chat-me .user-chat-list-body {
margin-right: 20upx;
margin-left: 100upx;
}
.user-chat-me .user-chat-list-body:after {
left: auto;
right: -56upx;
border-color: transparent transparent transparent #F4F4F4;
}
.user-chat-list-body>image {
max-width: 150upx;
max-height: 200upx;
}
.user-chat-time {
padding: 50upx 0;
color: #a2a2a2;
font-size: 24upx;
}
</style>
user-chat页面
<template>
<view>
<!-- 聊天列表 -->
<block v-for="(item,index) in list" :key="index">
<user-chat-list :item="item" :index="index"></user-chat-list>
</block>
<!-- 输入框 -->
<user-chat-bottom @submit="submit"></user-chat-bottom>
</view>
</template>
<script>
import userChatBottom from '@/components/user-chat/user-chat-bottom.vue';
import time from '../../common/time.js';
import userChatList from '@/components/user-list/user-chat-list.vue';
export default {
components: {
userChatBottom,
userChatList
},
data() {
return {
list: [{
isme: false,
userpic: "../../static/demo/userpic/11.jpg",
type: "text",
data: "哈哈哈",
time: "1555146412"
},
{
isme: true,
userpic: "../../static/demo/userpic/10.jpg",
type: "img",
data: "../../static/demo/3.jpg",
time: "1555146414",
}
]
}
},
onLoad() {
this.getData();
},
methods: {
getData() {
// 从服务器获取到的数据
let arr = [{
isme: false,
userpic: "../../static/demo/userpic/11.jpg",
type: "text",
data: "哈哈哈",
time: "1555146412"
},
{
isme: true,
userpic: "../../static/demo/userpic/10.jpg",
type: "img",
data: "../../static/demo/3.jpg",
time: "1555146414",
},
];
for (let i = 0; i < arr.length; i++) {
arr[i].gstime = time.gettime.getChatTime(arr[i].time, i > 0 ? arr[i - 1].time : 0);
}
this.list = arr;
},
submit(data) {
console.log(data);
}
}
}
</script>
<style>
</style>