基于Vue实现模拟微信聊天气泡效果

概要

css + vue实现微信聊天气泡效果

整体架构流程

本次分享使用了HBuilder开发工具,采用了uniapp 提供了vue3 默认开发项目模板,主要涉及到的知识点有vue.js Html css node javascript 的一些基本用法。今天的主题是实现微信的聊天的气泡效果,这里主要采用了伪类元素:after来实现的。大致实现效果如下图:

在这里插入图片描述
实现代码如下:

<template>
	<view class="content">
		<view v-for="(item,index) in conentList">
			<view v-if="item.type === 1" class="chartRow girlChart">
				<image class="headimg" v-if="item.type === 1" :src="item.headImgUrl" mode="widthFix"></image>
				<view class="imgBox" v-if="item.textType ==='image'">
					<image v-if="item.textType ==='image'" :src="item.content" mode="widthFix">
					</image>
				</view>
				<text class="text girlBackground" v-if="item.textType ==='text'">{{item.content}}</text>
			</view>
			<view v-else class="chartRow boyChart">
				<image class="headimg" v-if="item.type == 2" :src="item.headImgUrl" mode="widthFix">
				</image>
				<view class="imgBox" v-if="item.textType ==='image'">
					<image v-if="item.textType ==='image'" :src="item.content" mode="widthFix">
					</image>
				</view>
				<text class="text bodyBackground" v-if="item.textType ==='text'">{{item.content}}</text>
			</view>
		</view>

		<view class="chart-foot">
			<textarea class="inputText" v-model="myTextArea" @input="inputHandle"></textarea>
			<button class="btn" @click="sendBoy()">男生发送</button>
			<button class="btn" @click="sendGril()">女生发送</button>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				"myTextArea": "",
				"conentList": [{
						"id": 1,
						"type": 1,
						"headImgUrl": "/static/boy.jpeg",
						"textType": "text",
						"content": "看你朋友圈,你应该很喜欢养小动物吧!",
					},
					{
						"id": 2,
						"type": 2,
						"textType": "text",
						"headImgUrl": "/static/girl.jpeg",
						"content": "对呀,这都被你发现了,只是我爸妈不让我养.",
					},
					{
						"id": 3,
						"type": 1,
						"textType": "text",
						"headImgUrl": "/static/boy.jpeg",
						"content": "把你的兴趣给剥夺了,我之前养过一只萨摩,去年送给朋友了。",
					},
					{
						"id": 4,
						"type": 2,
						"textType": "text",
						"headImgUrl": "/static/girl.jpeg",
						"content": "你也喜欢养宠物啊?",
					},
					{
						"id": 5,
						"type": 1,
						"textType": "text",
						"headImgUrl": "/static/boy.jpeg",
						"content": "是啊,猜我现在养的啥?",
					},
					{
						"id": 6,
						"type": 2,
						"textType": "text",
						"headImgUrl": "/static/girl.jpeg",
						"content": "小猫?",
					},
					{
						"id": 7,
						"type": 1,
						"textType": "text",
						"headImgUrl": "/static/boy.jpeg",
						"content": "不对,养了一只小仓鼠",
					},
					{
						"id": 8,
						"type": 1,
						"textType": "image",
						"headImgUrl": "/static/boy.jpeg",
						"content": "/static/cangshu.jpg",
					},
					{
						"id": 9,
						"type": 2,
						"textType": "text",
						"headImgUrl": "/static/girl.jpeg",
						"content": "真的好可爱啊",
					},
					{
						"id": 10,
						"type": 2,
						"textType": "text",
						"headImgUrl": "/static/girl.jpeg",
						"content": "看的我也想养一只",
					}, {
						"id": 11,
						"type": 1,
						"textType": "text",
						"headImgUrl": "/static/boy.jpeg",
						"content": "要不我送你一只好啦",
					},
					{
						"id": 12,
						"type": 2,
						"textType": "text",
						"headImgUrl": "/static/girl.jpeg",
						"content": "真的吗?",
					}
				]
			}

		},
		onLoad() {

		},
		methods: {
			sendBoy: function() {
				let obj = {
					id: this.conentList.length + 1,
					"type": 1,
					"headImgUrl": "/static/boy.jpeg",
					"textType": "text",
					"content": this.myTextArea,
				}
				this.conentList.push(obj);
			},
			sendGril: function() {
				let obj = {
					id: this.conentList.length + 1,
					"type": 2,
					"headImgUrl": "/static/girl.jpeg",
					"textType": "text",
					"content": this.myTextArea,
				}
				this.conentList.push(obj);
			},
			inputHandle: function(e) {

			}
		}
	}
</script>

<style lang="scss" scoped>
	.content {
		width: 100%;
		height: 1670rpx;
		overflow-x: hidden;
		overflow-y: auto;
		background-color: #eee;
	}

	.charRow {
		width: 100%;
		height: 200rpx;
		position: relative;
	}

	.headimg {
		width: 150rpx;
		height: 150rpx;
	}

	.text {
		font-size: 32rpx;
		wdith: 100%;
		display: table;
		height: 30px;
		max-width: 300px;
		padding: 3px 6px;
		line-height: 30px;
		border-radius: 4px;
		overflow-wrap: anywhere;
		text-align: left;
	}

	.bodyBackground::after {
		position: absolute;
		right: -18px;
		top: 10px;
		content: '';
		border: 10px solid transparent;
		border-left-color: #9cda62;
	}

	.girlBackground::after {
		position: absolute;
		left: -18px;
		top: 10px;
		content: '';
		border: 10px solid transparent;
		border-right-color: white;
	}

	.imgBox {
		position: absolute;
		top: 0rpx;
		left: 160rpx;
		width: 100%;
		height: auto;
	}

	.girlChart {
		text-align: left;
		position: relative;
	}

	.boyChart {
		text-align: right;
		position: relative;
	}

	.girlBackground {
		background-color: white;
		border: 1rpx solid #eee;
		color: #000;
		position: absolute;
		left: 180rpx;
		top: 50rpx;
	}

	.bodyBackground {
		background-color: #9cda62;
		border: 1rpx solid #eee;
		color: #000;
		position: absolute;
		right: 100px;
		top: 50rpx;
	}

	.chart-foot {
		width: 100%;
		height: 100rpx;
		line-height: 100rpx;
		position: fixed;
		bottom: 0rpx;
		left: 0rpx;
		border: 1px solid #eee;
	}

	.inputText {
		text-align: left;
		width: 80%;
		height: 100rpx;
		float: left;
	}

	.btn {
		text-align: center;
		width: 10%;
		height: 100rpx;
		float: left;
	}
</style>

技术名词解释

Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。

小结

本次demo英用了v-for v-if v-model等指令进行数据渲染,通过vue的事件绑定,就可以手动发送男女聊天信息并展示界面上。我觉得特别巧妙的一点就是通过

.text {
		font-size: 32rpx;
		wdith: 100%;
		display: table;
		height: 30px;
		max-width: 300px;
		padding: 3px 6px;
		line-height: 30px;
		border-radius: 4px;
		overflow-wrap: anywhere;
		text-align: left;
	}

	.bodyBackground::after {
		position: absolute;
		right: -18px;
		top: 10px;
		content: '';
		border: 10px solid transparent;
		border-left-color: #9cda62;
	}

	.girlBackground::after {
		position: absolute;
		left: -18px;
		top: 10px;
		content: '';
		border: 10px solid transparent;
		border-right-color: white;
	}

样式就可以实现聊天的气泡效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue模拟微信聊天内容置底可以使用以下方法: 1. 使用 `ref` 绑定聊天内容区域的元素,并在 `mounted` 钩子函数中获取该元素的高度。 ```vue <template> <div class="chat-wrapper" ref="chatWrapper"> <!-- 聊天内容区域 --> </div> </template> <script> export default { mounted() { this.chatWrapperHeight = this.$refs.chatWrapper.clientHeight; } } </script> <style> .chat-wrapper { height: 300px; /* 聊天内容区域的高度 */ overflow-y: scroll; } </style> ``` 2. 监听聊天内容区域的高度变化,如果高度变大了,说明有新消息到来,将聊天内容区域的滚动条置于底部。 ```vue <template> <div class="chat-wrapper" ref="chatWrapper" @DOMNodeInserted="scrollToBottom"> <!-- 聊天内容区域 --> </div> </template> <script> export default { mounted() { this.chatWrapperHeight = this.$refs.chatWrapper.clientHeight; }, methods: { scrollToBottom() { const chatWrapper = this.$refs.chatWrapper; const isScrolledToBottom = chatWrapper.scrollHeight - chatWrapper.clientHeight <= chatWrapper.scrollTop + 1; if (isScrolledToBottom) { chatWrapper.scrollTop = chatWrapper.scrollHeight - chatWrapper.clientHeight; } } } } </script> <style> .chat-wrapper { height: 300px; /* 聊天内容区域的高度 */ overflow-y: scroll; } </style> ``` 这段代码使用了 `DOMNodeInserted` 事件来监听聊天内容区域的高度变化,一旦聊天内容区域的高度变大了,就将滚动条滚动到底部,使用户可以看到最新的消息。其中,`isScrolledToBottom` 变量用于判断滚动条是否已经滚动到底部,如果已经滚动到底部,则不需要再次滚动,避免出现滚动条抖动的情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值