<template> <view> <view class="tn-read-more-class tn-read-more"> <!-- 内容 --> <view :id="elId" class="tn-read-more__content" :style="[contentStyle]" > <slot></slot> </view> <!-- 展开收起按钮 --> <view v-if="isLongContent" class="tn-read-more__show-more__wrap" :class="{'tn-read-more__show-more': showMore}" :style="[innerShadowStyle]" @tap="toggleReadMore"> <text class="tn-read-more__show-more--text" :style="[fontStyle]">{{ showMore ? closeText : openText }}</text> <view class="tn-read-more__show-more--icon"> <view :class="[tipIconClass]" :style="[fontStyle]"></view> </view> </view> </view> </view> </template> <script> import componentsColorMixin from '../../libs/mixin/components_color.js' export default { name: 'tn-read-more', mixins: [componentsColorMixin], props: { // 默认占位高度 showHeight: { type: Number, default: 400 }, // 显示收起按钮 closeBtn: { type: Boolean, default: false }, // 展开提示文字 openText: { type: String, default: '展开阅读全文' }, // 收起提示文字 closeText: { type: String, default: '收起' }, // 展开提示图标 openIcon: { type: String, default: 'down' }, // 收起提示图标 closeIcon: { type: String, default: 'up' }, // 阴影样式 shadowStyle: { type: Object, default () { return { backgroundImage: "linear-gradient(-180deg, rgba(255, 255, 255, 0) 0%, #fff 80%)", paddingTop: "300rpx", marginTop: "-300rpx" } } }, // 组件标识 index: { type: [Number, String], default: '' } }, computed: { paramsChange() { return `${this.open}-${this.showHeight}` }, contentStyle() { let style = {} if (this.isLongContent && !this.showMore) { style.height = `${this.showHeight}rpx` } else { if (!this.initHeight) { style.height = 'auto' } else { style.height = `${this.contentHeight}px` } } return style }, innerShadowStyle() { let style = {} // 折叠时才需要阴影样式 if (!this.showMore) { style = Object.assign(style, this.shadowStyle) } return style }, fontStyle() { let style = {} style.color = this.fontColorStyle ? this.fontColorStyle : '#01BEFF' style.fontSize = this.fontSizeStyle ? this.fontSizeStyle : '28rpx' return style }, tipIconClass() { if (this.showMore) { if (this.closeIcon) { return `tn-icon-${this.closeIcon}` } } else { if (this.openIcon) { return `tn-icon-${this.openIcon}` } } } }, data() { return { elId: this.$t.uuid(), // 标记是否已经初始化高度完成 initHeight: false, // 是否需要隐藏一部分内容 isLongContent: false, // 当前展开的打开、关闭状态 showMore: false, // 内容的高度 contentHeight: 0 } }, watch: { paramsChange(value) { this.initHeight = false this.isLongContent = false this.showMore = true this.$nextTick(() => { this.init() }) } }, mounted() { this.$nextTick(() => { this.init() }) }, methods: { // 初始化组件 init() { // 判断高度,如果真实内容的高度大于占位高度,则显示展开与收起的控制按钮 this._tGetRect('#' + this.elId).then(res => { this.contentHeight = res.height this.initHeight = true if (res.height > uni.upx2px(this.showHeight)) { this.isLongContent = true this.showMore = false } }) }, // 展开或者收起内容 toggleReadMore() { this.showMore = !this.showMore // 是否显示收起按钮 if (!this.closeBtn) this.isLongContent = false this.$emit(this.showMore ? 'open' : 'closed', this.index) } } } </script> <style lang="scss" scoped> .tn-read-more { &__content { font-size: 28rpx; color: $tn-font-color; line-height: 1.8; text-align: left; overflow: hidden; transition: all 0.3s linear; } &__show-more { padding-top: 0; background: none; margin-top: 20rpx; &__wrap { position: relative; width: 100%; display: flex; flex-direction: row; align-items: center; justify-content: center; padding-bottom: 26rpx; } &--text { display: flex; flex-direction: row; align-items: center; justify-content: center; line-height: 1; } &--icon { margin-left: 14rpx; } } } </style>