TextClamp
使用 js 实现文本展开、收起,并非纯 CSS 实现。
Props:
- fontSize:Number,默认:14
- lines:Number,默认:1
- lineHeight:Number,默认:20
Feat:
- 监听插槽的变化(文本内容的变化),自动计算文本高度
- 展开、折叠时有 transition 效果
- 文本内容较少时(未超过行数 lines),不会展示按钮
Code
text-clamp.vue
<template>
<div class="text-clamp">
<div class="text" :style="{height}">
<span v-if="isVisible" class="btn" @click="toggle">{{isExpand ? '收起' : '... 展开'}}</span>
<div ref="textRef" :style="commonStyle">
<slot />
</div>
</div>
</div>
</template>
<script>
export default {
name: "TextClamp",
props: {
fontSize: {
type: Number,
default: 14
},
lines: {
type: Number,
default: 1
},
lineHeight: {
type: Number,
default: 20
},
selectors: {
type: String,
default: ""
}
},
data () {
return {
isExpand: false,
isVisible: false,
textHeight: 0
}
},
computed: {
height () {
if (this.isExpand) {
return this.$refs.textRef.clientHeight + 'px';
} else {
return Math.min((this.lines * this.lineHeight), this.textHeight) + 'px';
}
},
commonStyle () {
return {
lineHeight: this.lineHeight + 'px',
fontSize: this.fontSize + 'px',
}
}
},
mounted () {
this.init();
// 监听插槽变化
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === "characterData") {
this.init();
}
});
});
observer.observe(this.$refs.textRef, {
characterData: true,
subtree: true,
childList: true
});
},
methods: {
init () {
this.isExpand = false;
this.textHeight = this.$refs?.textRef?.clientHeight || 0;
this.isVisible = this.textHeight > this.lines * this.lineHeight;
},
toggle () {
this.isExpand = !this.isExpand;
if (!this.isExpand && this.selectors) {
const initEl = document.querySelector(this.selectors);
setTimeout(() => {
initEl.scrollIntoView({
behavior: 'smooth',
block: 'start',
inline: 'center'
});
}, 97)
}
}
}
}
</script>
<style lang="scss" scoped>
.text-clamp {
display: flex;
overflow: hidden;
}
.text {
font-size: 20px;
transition: 0.3s height;
}
.text::before {
content: "";
height: calc(100% - 20px);
float: right;
}
.btn {
float: right;
clear: both;
font-size: 12px;
line-height: 14px;
padding: 2px 6px;
background: #1890ff;
border-radius: 2px;
color: #fff;
cursor: pointer;
}
</style>
实例
<div style="min-height: 120px;">
<text-clamp :lines="6">123123</text-clamp>
</div>
<text-clamp :lines="5" :line-height="24">{{data || "--"}}</text-clamp>