Component({
properties: {
text: {
type: String,
value: ''
},
lines: {
type: Number,
observer(val) {
if (!/^[1-5]$/.test(val)) {
throw new Error(`lines field value can only be digits (1-5), Error value: ${value}`)
}
}
},
fontSize: {
type: String,
value: 14
},
color: {
type: String,
value: '#333'
},
lineHeight: {
type: Number,
value: 1.5,
observer(val) {
if (/^\d*$/.test(val)) {
throw new Error('lineHeight field value can only be digits')
}
}
},
closeText: {
type: String,
value: '展开'
},
openText: {
type: String,
value: '收起'
},
name: {
type: [String, Number],
value: ''
}
},
data: {
status: 'close',
unfold: true
},
lifetimes: {
ready() {
this.init()
}
},
methods: {
init() {
this.getContentHeight().then(height => {
const lineHeight = this.data.lineHeight * this.data.fontSize
const maxHeight = lineHeight * this.data.lines
if (maxHeight && maxHeight >= Math.floor(height)) {
this.setData({ unfold: true })
} else {
this.setData({ unfold: false })
}
})
},
getContentHeight() {
return new Promise(resolve => {
wx.createSelectorQuery()
.in(this)
.select('.read-more__content__text')
.boundingClientRect(res => {
resolve(res.height)
})
.exec()
})
},
toggleReadMore() {
const status = this.data.status === 'close' ? 'open' : 'close'
this.setData({ status })
this.triggerEvent(status, this.data.name)
}
}
})
<view class="read-more">
<view class="read-more__content line-clamp-{{lines}} {{status === 'open' ? 'open' : ''}}" style="font-size: {{fontSize}}; color: {{color}}; line-height: {{lineHeight}};">
<view class="read-more__toggle {{status === 'open' ? 'hidden-ellipsis' : '' }}" wx:if="{{lines && !unfold}}" catchtap="toggleReadMore">
<view class="read-more__toggle__text" style="color:#3673EA">
{{status === 'close' ? closeText : openText}}
</view>
</view>
<text class="read-more__content__text">{{text}}</text>
</view>
</view>
.read-more {
display: flex;
}
.read-more__content {
line-height: 1.5;
overflow: hidden;
text-align: justify;
overflow: hidden;
}
.read-more__content.open {
max-height: none;
}
.read-more__content::before {
content: '';
float: right;
margin-bottom: -1.45em;
width: 0;
height: 100%;
}
.read-more__toggle {
float: right;
clear: both;
display: flex;
align-items: center;
color: #3673ea;
}
.read-more__toggle.hidden-ellipsis::before {
visibility: hidden;
}
.read-more__toggle::before {
content: '...';
margin: 0 5px 0 0;
color: #333;
}
.line-clamp-1 {
max-height: 1.5em;
}
.line-clamp-2 {
max-height: 3em;
}
.line-clamp-3 {
max-height: 4.5em;
}
.line-clamp-4 {
max-height: 6em;
}
.line-clamp-5 {
max-height: 7.5em;
}