uniapp实现带展开收起按钮文本多行省略

展示效果

组件

javascript 复制代码
<template>
	<view class="address-container">
		<!-- 1. 实际显示的文本区域 -->
		<!-- 如果未展开:单行时限制宽度,多行时限制高度 -->
		<view v-if="!isExpanded" class="address-text"
			:class="{ 'line-clamp': !isExpanded && lines > 1, 'single-line': !isExpanded && lines === 1 }"
			:style="{ '-webkit-line-clamp': lines, '--clamp-lines': lines }">{{ address }}</view>

		<!-- 展开后显示的文本 -->
		<view v-else class="address-text is-expanded">{{ address }}</view>

		<!-- 2. 隐藏的探测层(仅在初始加载时渲染) -->
		<!-- 宽度探测:限制宽度为容器可用宽度,用于测高 -->
		<view v-if="!isExpanded && !showButton && probeWidth > 0" class="probe-width"
			:style="{ width: probeWidth + 'px' }" @change="onProbeHeightChange" id="probe-el">
			{{ address }}
		</view>

		<!-- 展开/收起按钮 -->
		<view v-if="showButton" class="toggle-btn" @click="toggleExpand">
			{{ isExpanded ? '收起' : '展开' }}
		</view>
	</view>
</template>

<script>
	export default {
		name: 'AddressExpand',
		props: {
			address: {
				type: String,
				default: ''
			},
			lines: {
				type: Number,
				default: 1
			}
		},
		data() {
			return {
				isExpanded: false,
				showButton: false,
				probeWidth: 0 // 动态获取的可用宽度
			}
		},
		mounted() {
			this.$nextTick(() => {
				this.measure();
			})
		},
		methods: {
			measure() {
				// 第一步:获取组件容器的实际宽度
				const query = uni.createSelectorQuery().in(this)
				query.select('.address-container').boundingClientRect(container => {
					if (!container) return;

					// 减去按钮预估宽度 (80rpx) 和文本右边距 (32rpx),得出文本的实际可用宽度
					const btnWidth = uni.upx2px(80);
					const marginRight = uni.upx2px(32);

					// 触发探测层渲染
					this.probeWidth = container.width - btnWidth - marginRight;

					// 第二步:延迟等待探测层 DOM 渲染完毕,去获取其真实高度
					this.$nextTick(() => {
						const probeQuery = uni.createSelectorQuery().in(this)
						probeQuery.select('#probe-el').boundingClientRect(el => {
							if (!el) return;

							// 计算单行高度 (fontSize: 28rpx, lineHeight: 1.4)
							const lineHeight = uni.upx2px(28) * 1.4;
							const maxHeight = lineHeight * this.lines;

							// 核心判断:真实高度 > 允许的最大高度 + 0.5px 误差阈值
							if (el.height > maxHeight + 0.5) {
								this.showButton = true;
							}
						}).exec()
					})
				}).exec()
			},

			toggleExpand() {
				this.isExpanded = !this.isExpanded;
				if (this.isExpanded) {
					this.probeWidth = 0; // 收起探测层
				}
			}
		}
	}
</script>

<style scoped>
	.address-container {
		display: flex;
		align-items: flex-end;
		margin: 20rpx;
		position: relative;
		box-sizing: border-box;
	}

	.address-text {
		flex: 1;
		font-size: 28rpx;
		color: #333;
		line-height: 1.4;
		word-break: break-all;
	}

	/* 单行省略样式 */
	.single-line {
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	/* 多行省略样式 */
	.line-clamp {
		display: -webkit-box;
		-webkit-box-orient: vertical;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: normal;
	}

	.is-expanded {
		white-space: normal;
		display: block;
	}

	/* 探测层:绝对定位,限制宽度,用于模拟真实文本溢出场景 */
	.probe-width {
		position: absolute;
		left: -9999px;
		font-size: 28rpx;
		color: transparent;
		line-height: 1.4;
		white-space: normal;
		word-break: break-all;
	}

	.toggle-btn {
		flex-shrink: 0;
		font-size: 26rpx;
		color: #1296db;
		white-space: nowrap;
		line-height: 1.4;
		margin-top: 0rpx;
	}
</style>

引用

javascript 复制代码
<template>
	<view>
		<!-- 短地址 -->
		<AddressExpand address="广东省深圳市南山区" />
		<!-- 长地址 -->
		<AddressExpand address="广东省深圳市南山区粤海街道与金融大路交汇保安金融大厦南门101室" />
		<!-- 两行省略 -->
		<AddressExpand address="广东省深圳市南山区粤海街道与金融大路交汇保安金融大厦南门101室,这里是第二行测试文本,如果超过两行就会显示按钮" :lines="2" />
	</view>
</template>

<script>
	import AddressExpand from '@/components/AddressExpand/AddressExpand.vue'

	export default {
		components: {
			AddressExpand
		}
	}
</script>
相关推荐
Liu.7741 小时前
uniapp swiper 常见问题及修复
前端·uni-app
Liu.7742 小时前
uniapp scroll-view 常见问题及修复
uni-app
梦曦i5 小时前
Taro vs uni-app:技术路线与选型真相
uni-app·taro
多客:duokelijie5 小时前
婚恋交友小程序合规梳理:上线运营需要准备哪些资质与许可手续?
后端·mysql·微信小程序·前端框架·uni-app·php·持续部署
PedroQue991 天前
unix-utils v0.2.0 发布:modal 全端统一,自绘窗口解决输入框难题
前端·uni-app
2301_32241428043 天前
springboot学生课堂出勤统计系统15835-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·mysql·随机森林·微信小程序·uni-app·微信开发者工具·推荐算法
2501_915921435 天前
iOS应用从开发到上架App Store的完整步骤详解
android·ios·小程序·https·uni-app·iphone·webview
小蒜学长7 天前
基于SpringBoot+uni-app的闪洁家政系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·uni-app·家政服务
anyup_前端梦工厂7 天前
uni-app 模板 Starter 一键清理 Skill 发布
前端·人工智能·uni-app