效果图
代码
<template><div class="m-text-overflow modules"><div class="l-content" :style="contentStyle"><div ref="refContent"><slot><span v-html="content"> </span></slot></div></div><div class="l-show-more" v-if="isClose"><div class="l-show-more__text" @click="handleShowMore"><slot name="showMore">{{ showMoreText }}</slot></div></div></div>
</template>
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';
@Component({components: {},
})
export default class MTextOverflow extends Vue {@Prop({ default: '' }) protected content!: string;@Prop({ default: 100 }) protected height!: number;@Prop({ default: '点击查看更多' }) protected showMoreText!: string;status: 'open' | 'close' = 'close';mutationObserver: MutationObserver | null = null;get isOpen(): boolean {return this.status === 'open';}get isClose(): boolean {return this.status === 'close';}get contentStyle() {if (this.isClose) {return {height: `${this.height}px`,};}return {};}mounted() {this.handleContent();this.mutationObserver = new MutationObserver(() => {this.handleContent();});if (this.$refs.refContent) {this.mutationObserver.observe(this.$refs.refContent as Element, {childList: true,attributes: true,characterData: true,subtree: true,});}}handleContent() {if ((this.$refs.refContent as Element).getBoundingClientRect().height > this.height) {this.status = 'close';} else {this.status = 'open';}}handleShowMore() {this.status = 'open';}destroyed() {this.mutationObserver?.disconnect();}
}
</script>
<style lang="scss" scoped>
.m-text-overflow.modules {background: #f7f7f7;padding: 16rpx;position: relative;.l {&-content {overflow: hidden;}&-show-more {position: absolute;left: 0;right: 0;bottom: 0;text-align: center;padding-top: 40rpx;background-image: linear-gradient(-180deg, rgba(255, 255, 255, 0) 0%, #fff 100%);z-index: 10;&__text {display: inline-block;cursor: pointer;margin-bottom: 20rpx;}}}
}
</style>```