u-read-more.vue
4.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<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>