You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
4.4 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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>