需求
文本超出后需要显示省略号并且省略号后面需要有更多和收起按钮的功能
实现思路
把 文本 和 .... 更多 都放在一个容器内,计算容器的 scrollHeight 和 clientHeight,这里面需要不断从 文本 的最后开始删减字符,知道删减的字符和 ... 更多 加起来更好是你需要显示的行数,为了之后还原 文本 所以还需要备份一下 文本,至于怎么一个个删减字符达到刚好的行数这里面需要用到递归。下面呢是我实现的代码
代码
<template>
<div class="typography" :class="{ isMore: isMore && isPackUp }">
<div class="text multi-text" :class="{ showAll: isMore }" ref="multi">
{{ description }}
<span v-if="isSuffix && !isMore">....</span>
<span class="text more" v-if="isSuffix && !isMore" @click="reset">
{{ $t('more') }}
</span>
<div class="text more pack-up" v-if="isMore && isPackUp" @click="packUp">
{{ $t('packUp') }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isSuffix: false,
isMore: false,
isPackUp: false,
count: 0,
description: this.$t('typography'),
originDesc: this.$t('typography'),
}
},
mounted() {
this.computeDesc()
window.addEventListener('resize',this.onResize)
},
beforeDestroy(){
window.removeEventListener('resize',this.onResize)
},
methods: {
onResize(){
this.description = this.originDesc
this.isSuffix = false
this.isMore = false
this.isPackUp = false
this.computeDesc()
},
// 计算 description 的高度
getDescHeight() {
let heightObj = {}
this.$nextTick(() => {
let multi = this.$refs.multi
// console.log(multi)
if (multi) {
console.log('scrollHeight', multi.scrollHeight)
console.log('clientHeight', multi.clientHeight)
heightObj.scrollHeight = multi.scrollHeight
heightObj.clientHeight = multi.clientHeight
}
})
return heightObj
},
// 从后往前删减 description 的字符
async computeDesc() {
const heightObj = await this.getDescHeight()
// console.log('height', heightObj)
const { scrollHeight, clientHeight } = heightObj
if (this.count === 0 && scrollHeight === clientHeight) {
this.isMore = true
this.isPackUp = false
return
}
if (scrollHeight > clientHeight) {
this.description = this.description.slice(
0,
this.description.length - 1
)
// console.log('description', this.tokenDetail.description)
this.count++
this.isSuffix = true
this.computeDesc()
}
},
packUp() {
this.isMore = false
this.isPackUp = false
this.computeDesc()
},
reset() {
this.description = this.originDesc
this.isMore = true
this.isPackUp = true
},
},
}
</script>
<style lang="scss" scoped>
.typography {
padding: 0.2rem 0.32rem;
border: 0.01rem solid #999;
border-radius: 0.16rem;
&.isMore {
padding: 0.2rem 0.32rem 0.38rem;
}
position: relative;
.multi-text {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4;
overflow: hidden;
&.showAll {
-webkit-line-clamp: 999;
}
.more {
cursor: pointer;
color: #2980fe;
}
.pack-up {
position: absolute;
right: 0.42rem;
bottom: 0.1rem;
}
}
}
</style>
也可以在codepen预览 codepen.io/ycg5250/pen…
至于宽度改变之后, 可以用 window.onresize来监听窗口的大小变化,不过这个我只是测试了一下还行,也可以去掉。