通過line-height和max-height控制行數(shù)
通過偽元素和float把展開按鈕定位在文本右下角
通過boundingClientRect獲取文本總行數(shù),來判斷是否需要展開按鈕
expandable_text.vue組件完整代碼:
<template>
<view class="container"
:style="{ '--font-size': fontSize + 'rpx', '--text-color': textColor, '--show-ellipsis': expand ? 'hidden' : 'visible' }">
<view id="info" class="info-label" :style="{ maxHeight: expand ? 'none' : 1.5 * maxLine + 'em' }">
<text v-if="showBtn" class="expand-label" @click.stop="onClickExpand">{{ expand ? '收起' : '展開' }}</text>
{{ text }}
</view>
</view>
</template>
<script>
export default {
props: {
// 文本
text: {
type: String,
default: ''
},
// 字號(hào)
fontSize: {
type: Number,
default: 28
},
// 文字顏色
textColor: {
type: String,
default: '#333'
},
// 收起時(shí)最大行數(shù)
maxLine: {
type: Number,
default: 1,
}
},
data() {
return {
showBtn: false, // 是否顯示展開按鈕
expand: false, // 文字是否展開
}
},
mounted() {
uni.createSelectorQuery().in(this).select('#info').boundingClientRect(rect => {
// 文字行數(shù)
let lineCount = parseInt(rect.height / uni.upx2px(this.fontSize))
this.showBtn = lineCount > this.maxLine
console.log(`行數(shù):${lineCount} ${this.showBtn}`)
}).exec()
},
methods: {
// 展開/收起
onClickExpand() {
this.expand = !this.expand
}
}
}
</script>
<style scoped>
.container {
display: flex;
}
.info-label {
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
line-height: 1.5;
text-align: justify;
font-size: var(--font-size);
color: var(--text-color);
}
.info-label::before {
content: '';
float: right;
width: 0;
height: 100%;
margin-bottom: calc(var(--font-size) * -1.5);
}
.expand-label {
float: right;
clear: both;
color: dodgerblue;
}
.expand-label::before {
content: '...';
color: var(--text-color);
visibility: var(--show-ellipsis);
}
</style>
使用方法:
text:文本字符串
fontSize:文本字號(hào),int類型
textColor:文本顏色,string類型
maxLine:文本收起時(shí)最大行數(shù),int類型
<ExpandableText :text="text" :fontSize="28" :maxLine="2"></ExpandableText>
效果:

image.png

image.png