<template> 
 | 
    <view class="u-read-more"> 
 | 
        <view 
 | 
            class="u-read-more__content" 
 | 
            :style="{ 
 | 
                height: isLongContent && status === 'close' ? $u.addUnit(showHeight) : $u.addUnit(contentHeight), 
 | 
                textIndent: textIndent 
 | 
            }" 
 | 
        > 
 | 
            <view 
 | 
                class="u-read-more__content__inner" 
 | 
                ref="u-read-more__content__inner" 
 | 
                :class="[elId]" 
 | 
            > 
 | 
                <slot></slot> 
 | 
            </view> 
 | 
        </view> 
 | 
        <view 
 | 
            class="u-read-more__toggle" 
 | 
            :style="[innerShadowStyle]" 
 | 
            v-if="isLongContent" 
 | 
        > 
 | 
            <slot name="toggle"> 
 | 
                <view 
 | 
                    class="u-read-more__toggle__text" 
 | 
                    @tap="toggleReadMore" 
 | 
                > 
 | 
                    <u--text 
 | 
                        :text="status === 'close' ? closeText : openText" 
 | 
                        :color="color" 
 | 
                        :size="fontSize" 
 | 
                        :lineHeight="fontSize" 
 | 
                        margin="0 5px 0 0" 
 | 
                    ></u--text> 
 | 
                    <view class="u-read-more__toggle__icon"> 
 | 
                        <u-icon 
 | 
                            :color="color" 
 | 
                            :size="fontSize + 2" 
 | 
                            :name="status === 'close' ? 'arrow-down' : 'arrow-up'" 
 | 
                        ></u-icon> 
 | 
                    </view> 
 | 
                </view> 
 | 
            </slot> 
 | 
        </view> 
 | 
    </view> 
 | 
</template> 
 | 
  
 | 
<script> 
 | 
    // #ifdef APP-NVUE 
 | 
    const dom = uni.requireNativePlugin('dom') 
 | 
    // #endif 
 | 
    import props from './props.js'; 
 | 
    /** 
 | 
     * readMore 阅读更多 
 | 
     * @description 该组件一般用于内容较长,预先收起一部分,点击展开全部内容的场景。 
 | 
     * @tutorial https://www.uviewui.com/components/readMore.html 
 | 
     * @property {String | Number}    showHeight    内容超出此高度才会显示展开全文按钮,单位px(默认 400 ) 
 | 
     * @property {Boolean}            toggle        展开后是否显示收起按钮(默认 false ) 
 | 
     * @property {String}            closeText    关闭时的提示文字(默认 '展开阅读全文' ) 
 | 
     * @property {String}            openText    展开时的提示文字(默认 '收起' ) 
 | 
     * @property {String}            color        提示文字的颜色(默认 '#2979ff' ) 
 | 
     * @property {String | Number}    fontSize    提示文字的大小,单位px (默认 14 ) 
 | 
     * @property {Object}            shadowStyle    显示阴影的样式 
 | 
     * @property {String}            textIndent    段落首行缩进的字符个数 (默认 '2em' ) 
 | 
     * @property {String | Number}    name        用于在 open 和 close 事件中当作回调参数返回 
 | 
     * @event {Function} open 内容被展开时触发 
 | 
     * @event {Function} close 内容被收起时触发 
 | 
     * @example <u-read-more><rich-text :nodes="content"></rich-text></u-read-more> 
 | 
     */ 
 | 
    export default { 
 | 
        name: 'u-read-more', 
 | 
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props], 
 | 
        data() { 
 | 
            return { 
 | 
                isLongContent: false, // 是否需要隐藏一部分内容 
 | 
                status: 'close', // 当前隐藏与显示的状态,close-收起状态,open-展开状态 
 | 
                elId: uni.$u.guid(), // 生成唯一class 
 | 
                contentHeight: 100, // 内容高度 
 | 
            } 
 | 
        }, 
 | 
        computed: { 
 | 
            // 展开后无需阴影,收起时才需要阴影样式 
 | 
            innerShadowStyle() { 
 | 
                if (this.status === 'open') return {} 
 | 
                else return this.shadowStyle 
 | 
            } 
 | 
        }, 
 | 
        mounted() { 
 | 
            this.init() 
 | 
        }, 
 | 
        methods: { 
 | 
            async init() { 
 | 
                this.getContentHeight().then(height => { 
 | 
                    this.contentHeight = height 
 | 
                    // 判断高度,如果真实内容高度大于占位高度,则显示收起与展开的控制按钮 
 | 
                    if (height > uni.$u.getPx(this.showHeight)) { 
 | 
                        this.isLongContent = true 
 | 
                        this.status = 'close' 
 | 
                    } 
 | 
                }) 
 | 
            }, 
 | 
            // 获取内容的高度 
 | 
            async getContentHeight() { 
 | 
                // 延时一定时间再获取节点 
 | 
                await uni.$u.sleep(30) 
 | 
                return new Promise(resolve => { 
 | 
                    // #ifndef APP-NVUE 
 | 
                    this.$uGetRect('.' + this.elId).then(res => { 
 | 
                        resolve(res.height) 
 | 
                    }) 
 | 
                    // #endif 
 | 
  
 | 
                    // #ifdef APP-NVUE 
 | 
                    const ref = this.$refs['u-read-more__content__inner'] 
 | 
                    dom.getComponentRect(ref, (res) => { 
 | 
                        resolve(res.size.height) 
 | 
                    }) 
 | 
                    // #endif 
 | 
                }) 
 | 
            }, 
 | 
            // 展开或者收起 
 | 
            toggleReadMore() { 
 | 
                this.status = this.status === 'close' ? 'open' : 'close' 
 | 
                // 如果toggle为false,隐藏"收起"部分的内容 
 | 
                if (this.toggle == false) this.isLongContent = false 
 | 
                // 发出打开或者收齐的事件 
 | 
                this.$emit(this.status, this.name) 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
</script> 
 | 
  
 | 
<style lang="scss" scoped> 
 | 
@import "../../libs/css/components.scss"; 
 | 
  
 | 
.u-read-more { 
 | 
  
 | 
    &__content { 
 | 
        overflow: hidden; 
 | 
        color: $u-content-color; 
 | 
        font-size: 15px; 
 | 
        text-align: left; 
 | 
    } 
 | 
  
 | 
    &__toggle { 
 | 
        @include flex; 
 | 
        justify-content: center; 
 | 
  
 | 
        &__text { 
 | 
            @include flex; 
 | 
            align-items: center; 
 | 
            justify-content: center; 
 | 
            margin-top: 5px; 
 | 
        } 
 | 
    } 
 | 
} 
 | 
</style> 
 |