Blame view

uni_modules/uview-plus/components/u-read-more/u-read-more.vue 4.69 KB
a2702f6d   刘淇   巡查计划
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
158
159
160
161
162
163
164
165
  <template>
  	<view class="u-read-more">
  		<view
  		    class="u-read-more__content"
  		    :style="{
  				height: isLongContent && status === 'close' ? addUnit(showHeight) : 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"
  				>
  					<up-text
  					    :text="status === 'close' ? closeText : openText"
  					    :color="color"
  					    :size="fontSize"
  					    :lineHeight="fontSize"
  					    margin="0 5px 0 0"
  					></up-text>
  					<view class="u-read-more__toggle__icon">
  						<up-icon
  						    :color="color"
  						    :size="fontSize + 2"
  						    :name="status === 'close' ? 'arrow-down' : 'arrow-up'"
  						></up-icon>
  					</view>
  				</view>
  			</slot>
  		</view>
  	</view>
  </template>
  
  <script>
  	// #ifdef APP-NVUE
  	const dom = uni.requireNativePlugin('dom')
  	// #endif
  	import { props } from './props';
  	import { mpMixin } from '../../libs/mixin/mpMixin';
  	import { mixin } from '../../libs/mixin/mixin';
  	import { addUnit, guid, getPx, sleep } from '../../libs/function/index';
  	/**
  	 * readMore 阅读更多
  	 * @description 该组件一般用于内容较长,预先收起一部分,点击展开全部内容的场景。
  	 * @tutorial https://uview-plus.jiangruyi.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: [mpMixin, mixin, props],
  		data() {
  			return {
  				isLongContent: false, // 是否需要隐藏一部分内容
  				status: 'close', // 当前隐藏与显示的状态,close-收起状态,open-展开状态
  				elId: guid(), // 生成唯一class
  				contentHeight: 100, // 内容高度
  			}
  		},
  		computed: {
  			// 展开后无需阴影,收起时才需要阴影样式
  			innerShadowStyle() {
  				if (this.status === 'open') return {}
  				else return this.shadowStyle
  			}
  		},
  		mounted() {
  			this.init()
  		},
  		emits: ["open", "close"],
  		methods: {
  			addUnit,
  			async init() {
  				this.getContentHeight().then(height => {
  					this.contentHeight = height
  					// 判断高度,如果真实内容高度大于占位高度,则显示收起与展开的控制按钮
  					if (height > getPx(this.showHeight)) {
  						this.isLongContent = true
  						this.status = 'close'
  					} else {
  						// https://github.com/ijry/uview-plus/issues/270
  						this.isLongContent = false
  						this.status = 'close'
  					}
  				})
  			},
  			// 获取内容的高度
  			async getContentHeight() {
  				// 延时一定时间再获取节点
  				await 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>
  .u-read-more {
  
  	&__content {
  		overflow: hidden;
  		color: $u-content-color;
  		font-size: 15px;
  		text-align: left;
  	}
  
  	&__toggle {
  		@include flex;
  		justify-content: center;
  		position: relative;
  
  		&__text {
  			@include flex;
  			align-items: center;
  			justify-content: center;
  			margin-top: 5px;
  		}
  	}
  }
  </style>