仿微信聊天组界面实现

3,764 阅读2分钟

项目介绍

在 uniapp 中利用 flex 布局实现了一个仿微信的聊天组界面,主要是 css 层的知识,同样适用于其他前端环境。如果使用 Hbuilder 直接运行该项目即可,如果只是想移植 html 和 css 实现布局效果,查看 pages/index/index.vue 即可。

github地址: github.com/zifeiyu666/…

解决了什么问题?

  1. 即时通信聊天组/群聊中不同人数头像显示问题。
  2. 聊天组最近一次聊天内容长度超出的显示处理。
  3. 聊天组标题很长的时候显示省略号,并且聊天组宽度是自适应的。

使用的技术和技巧

  1. 头像显示
    1. 利用 flex 布局实现了不同尺寸头像的显示效果
    2. justify-content: center; align-items:center; align-content: center;三个属性联合使用实现了头像的水平处置居中
    3. flex-wrap: wrap-reverse; 实现了换行的时候从下往上排
  2. 聊天组标题名称和时间的显示格式
    1. 聊天组标题和时间分别居左居右,利用 justify-content: space-between 实现
    2. 聊天组标题超宽显示省略号会把时间挤到换行
    	.title-text{
    		overflow: hidden;
    		text-overflow: ellipsis;
    		white-space: nowrap;
    	}
    	.time{
    		white-space: nowrap; // 这里为了防止时间被挤到变形
    	}
    

源码展示

<template>
	<view>
		<view class="list" v-for='(item, index) in list' :key='index'>
			<view class="avatar" v-if='item.avatarList.length > 9'>
				<img :src="i" alt="" class='avatar-img-small' v-for='(i, index) in item.avatarList.slice(0,9)' :key='index'>
			</view>
			<view class="avatar" v-else-if='item.avatarList.length > 4'>
				<img :src="i" alt="" class='avatar-img-small' v-for='(i, index) in item.avatarList' :key='index'>
			</view>
			<view class="avatar" v-else-if='item.avatarList.length > 1'>
				<img :src="i" alt="" class='avatar-img-middle' v-for='(i, index) in item.avatarList' :key='index'>
			</view>
			<view class="avatar" v-else>
				<img :src="i" alt="" class='avatar-img-big' v-for='(i, index) in item.avatarList' :key='index'>
			</view>
			<view class="content">
				<view class="title">
					<text class='title-text'>{{item.name}}</text>
					<text class="time">{{item.lastMsg.time}}</text>
				</view>
				<view class='msg'>{{item.lastMsg.username}}:{{item.lastMsg.msg}}</view>
			</view>
		</view>
	</view>
	
</template>

<script>
	import demoList from '@/demo.json'
	export default {
		data() {
			return {
				title: 'Hello',
				list: demoList.list
			}
		},
		onLoad() {

		},
		methods: {

		}
	}
</script>

<style>
	.list{
		display: flex;
		/* margin-bottom: 20upx; */
		padding: 20upx;
	}
	.avatar{
		background-color: #F1F1F1;
		border-radius: 8upx;
		min-width: 100upx;
		max-width: 100upx;
		min-height: 100upx;
		max-height: 100upx;
		display: flex;
		justify-content: center;
		align-items: center;
		align-content: center;
		flex-wrap: wrap-reverse;
		margin-right: 20upx;
	}
	.avatar-img-big{
		width: 98%;
		margin: 1%;
	}
	.avatar-img-middle{
		width: 47%;
		margin: 1%;
	}
	.avatar-img-small{
		width: 31%;
		margin: 1%;
	}
	.title{
		font-size: 32upx;
		width: 100%;
		display: flex;
		justify-content: space-between;
	}
	.title-text{
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}
	.time{
		font-size: 28upx;
		color: #C0C0C0;
		white-space: nowrap;
	}
	.content{
		overflow: hidden;
		flex-grow: 1;
		justify-content: center;
		display: flex;
		flex-direction: column;
	}
	.msg{
		width: 100%;
		font-size: 28upx;
		color: #C0C0C0;
		overflow: hidden;
		text-overflow:ellipsis;
		white-space: nowrap;
	}
</style>