hy-app 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/common/shakeService.ts +31 -29
- package/components/avatar.zip +0 -0
- package/components/hy-action-sheet/hy-action-sheet.vue +71 -46
- package/components/hy-address-picker/hy-address-picker.vue +94 -83
- package/components/hy-avatar/hy-avatar.vue +84 -85
- package/components/hy-back-top/hy-back-top.vue +8 -6
- package/components/hy-badge/hy-badge.vue +47 -46
- package/components/hy-button/hy-button.vue +117 -93
- package/components/hy-calendar/hy-calendar.vue +168 -160
- package/components/hy-card/hy-card.vue +50 -43
- package/components/hy-card/typing.d.ts +33 -32
- package/components/hy-cell/hy-cell.vue +73 -51
- package/components/hy-check-button/hy-check-button.vue +54 -47
- package/components/hy-checkbox/hy-checkbox.vue +97 -105
- package/components/hy-code-input/hy-code-input.vue +80 -89
- package/components/hy-config-provider/hy-config-provider.vue +20 -21
- package/components/hy-count-down/hy-count-down.vue +66 -67
- package/components/hy-count-to/hy-count-to.vue +105 -99
- package/components/hy-count-to/typing.d.ts +13 -12
- package/components/hy-datetime-picker/hy-datetime-picker.vue +261 -253
- package/components/hy-datetime-picker/typing.d.ts +42 -40
- package/components/hy-divider/hy-divider.vue +68 -73
- package/components/hy-dropdown/hy-dropdown.vue +20 -19
- package/components/hy-dropdown-item/hy-dropdown-item.vue +66 -61
- package/components/hy-dropdown-item/typing.d.ts +9 -9
- package/components/hy-empty/hy-empty.vue +42 -42
- package/components/hy-flex/hy-flex.vue +99 -0
- package/components/hy-flex/index.scss +8 -0
- package/components/hy-flex/typing.d.ts +23 -0
- package/components/hy-float-button/hy-float-button.vue +218 -210
- package/components/hy-folding-panel/hy-folding-panel.vue +32 -33
- package/components/hy-form/hy-form.vue +264 -252
- package/components/hy-form/typing.d.ts +4 -0
- package/components/hy-form-group/hy-form-group.vue +114 -183
- package/components/hy-form-item/hy-form-item.vue +12 -10
- package/components/hy-form-item/index.scss +2 -2
- package/components/hy-form-item/typing.d.ts +3 -6
- package/components/hy-grid/hy-grid.vue +44 -43
- package/components/hy-icon/hy-icon.vue +61 -67
- package/components/hy-image/hy-image.vue +112 -88
- package/components/hy-image/typing.d.ts +27 -23
- package/components/hy-input/hy-input.vue +157 -127
- package/components/hy-input/typing.d.ts +53 -47
- package/components/hy-line/hy-line.vue +26 -26
- package/components/hy-line-progress/hy-line-progress.vue +42 -35
- package/components/hy-list/hy-list.vue +76 -85
- package/components/hy-loading/hy-loading.vue +26 -23
- package/components/hy-login/TheUserLogin.vue +1 -1
- package/components/hy-menu/hy-menu.vue +48 -43
- package/components/hy-menu/typing.d.ts +18 -17
- package/components/hy-modal/hy-modal.vue +39 -35
- package/components/hy-navbar/hy-navbar.vue +25 -25
- package/components/hy-navbar/typing.d.ts +24 -22
- package/components/hy-notice-bar/hy-notice-bar.vue +26 -27
- package/components/hy-notify/hy-notify.vue +53 -53
- package/components/hy-number-step/hy-number-step.vue +134 -146
- package/components/hy-number-step/typing.d.ts +35 -35
- package/components/hy-overlay/hy-overlay.vue +23 -21
- package/components/hy-pagination/hy-pagination.vue +41 -36
- package/components/hy-picker/hy-picker.vue +184 -154
- package/components/hy-picker/typing.d.ts +39 -39
- package/components/hy-popover/hy-popover.vue +97 -77
- package/components/hy-popup/hy-popup.vue +107 -98
- package/components/hy-price/hy-price.vue +38 -34
- package/components/hy-qrcode/hy-qrcode.vue +50 -51
- package/components/hy-radio/hy-radio.vue +101 -113
- package/components/hy-rate/hy-rate.vue +107 -88
- package/components/hy-read-more/hy-read-more.vue +64 -49
- package/components/hy-scroll-list/hy-scroll-list.vue +45 -48
- package/components/hy-search/hy-search.vue +73 -66
- package/components/hy-search/typing.d.ts +36 -35
- package/components/hy-signature/hy-signature.vue +282 -240
- package/components/hy-slider/hy-slider.vue +195 -153
- package/components/hy-slider/typing.d.ts +21 -21
- package/components/hy-steps/hy-steps.vue +118 -90
- package/components/hy-steps/index.scss +31 -21
- package/components/hy-submit-bar/hy-submit-bar.vue +61 -70
- package/components/hy-subsection/hy-subsection.vue +99 -102
- package/components/hy-subsection/typing.d.ts +19 -19
- package/components/hy-swipe-action/hy-swipe-action.vue +131 -118
- package/components/hy-swiper/hy-swiper.vue +85 -71
- package/components/hy-switch/hy-switch.vue +67 -72
- package/components/hy-switch/typing.d.ts +21 -19
- package/components/hy-tabs/hy-tabs.vue +168 -113
- package/components/hy-tag/hy-tag.vue +90 -86
- package/components/hy-tag/typing.d.ts +26 -21
- package/components/hy-text/hy-text.vue +119 -111
- package/components/hy-textarea/hy-textarea.vue +100 -93
- package/components/hy-textarea/typing.d.ts +36 -31
- package/components/hy-toast/hy-toast.vue +77 -67
- package/components/hy-tooltip/hy-tooltip.vue +109 -91
- package/components/hy-transition/hy-transition.vue +62 -66
- package/components/hy-upload/hy-upload.vue +294 -152
- package/components/hy-upload/typing.d.ts +41 -36
- package/components/hy-warn/hy-warn.vue +34 -27
- package/components/hy-waterfall/hy-waterfall.vue +83 -74
- package/components/hy-watermark/hy-watermark.vue +134 -115
- package/components/index.ts +1 -1
- package/composables/usePopover.ts +236 -221
- package/composables/useQueue.ts +53 -52
- package/global.d.ts +1 -0
- package/package.json +2 -2
- package/store/index.ts +9 -1
- package/theme.scss +5 -5
- package/typing/index.ts +0 -1
- package/typing/modules/common.d.ts +0 -2
- package/web-types.json +1 -1
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<view class="hy-rate" :id="elId" ref="hy-rate" :style="[customStyle]">
|
|
3
|
-
<view
|
|
3
|
+
<view
|
|
4
|
+
class="hy-rate__content"
|
|
5
|
+
@touchmove.stop="touchMove"
|
|
6
|
+
@touchend.stop="touchEnd"
|
|
7
|
+
>
|
|
4
8
|
<view
|
|
5
9
|
class="hy-rate__content__item cursor-pointer"
|
|
6
10
|
v-for="(item, index) in Number(count)"
|
|
@@ -15,7 +19,11 @@
|
|
|
15
19
|
<HyIcon
|
|
16
20
|
:name="Math.floor(activeIndex) > index ? activeIcon : inactiveIcon"
|
|
17
21
|
:color="
|
|
18
|
-
disabled
|
|
22
|
+
disabled
|
|
23
|
+
? '#c8c9cc'
|
|
24
|
+
: Math.floor(activeIndex) > index
|
|
25
|
+
? activeColor
|
|
26
|
+
: inactiveColor
|
|
19
27
|
"
|
|
20
28
|
:custom-style="{
|
|
21
29
|
padding: `0 ${addUnit(gutter / 2)}`,
|
|
@@ -37,7 +45,11 @@
|
|
|
37
45
|
<HyIcon
|
|
38
46
|
:name="Math.ceil(activeIndex) > index ? activeIcon : inactiveIcon"
|
|
39
47
|
:color="
|
|
40
|
-
disabled
|
|
48
|
+
disabled
|
|
49
|
+
? '#c8c9cc'
|
|
50
|
+
: Math.ceil(activeIndex) > index
|
|
51
|
+
? activeColor
|
|
52
|
+
: inactiveColor
|
|
41
53
|
"
|
|
42
54
|
:custom-style="{
|
|
43
55
|
padding: `0 ${addUnit(gutter / 2)}`,
|
|
@@ -52,29 +64,29 @@
|
|
|
52
64
|
|
|
53
65
|
<script lang="ts">
|
|
54
66
|
export default {
|
|
55
|
-
name:
|
|
67
|
+
name: "hy-rate",
|
|
56
68
|
options: {
|
|
57
69
|
addGlobalClass: true,
|
|
58
70
|
virtualHost: true,
|
|
59
|
-
styleIsolation:
|
|
71
|
+
styleIsolation: "shared",
|
|
60
72
|
},
|
|
61
|
-
}
|
|
73
|
+
};
|
|
62
74
|
</script>
|
|
63
75
|
|
|
64
76
|
<script setup lang="ts">
|
|
65
|
-
import { addUnit, getRect, guid, range, sleep } from
|
|
66
|
-
import { ref, watch,
|
|
67
|
-
import type { CSSProperties, PropType } from
|
|
68
|
-
import type { IRateEmits } from
|
|
69
|
-
import { IconConfig } from
|
|
77
|
+
import { addUnit, getRect, guid, range, sleep } from "../../utils";
|
|
78
|
+
import { ref, watch, onMounted, getCurrentInstance } from "vue";
|
|
79
|
+
import type { CSSProperties, PropType } from "vue";
|
|
80
|
+
import type { IRateEmits } from "./typing";
|
|
81
|
+
import { IconConfig } from "../../config";
|
|
70
82
|
// 组件
|
|
71
|
-
import HyIcon from
|
|
83
|
+
import HyIcon from "../hy-icon/hy-icon.vue";
|
|
72
84
|
|
|
73
85
|
/**
|
|
74
86
|
* 该组件一般用于满意度调查,星型评分的场景。
|
|
75
87
|
* @displayName hy-rate
|
|
76
88
|
*/
|
|
77
|
-
defineOptions({})
|
|
89
|
+
defineOptions({});
|
|
78
90
|
|
|
79
91
|
// const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
80
92
|
const props = defineProps({
|
|
@@ -106,12 +118,12 @@ const props = defineProps({
|
|
|
106
118
|
/** 未激活星星的颜色 */
|
|
107
119
|
inactiveColor: {
|
|
108
120
|
type: String,
|
|
109
|
-
default:
|
|
121
|
+
default: "#b2b2b2",
|
|
110
122
|
},
|
|
111
123
|
/** 激活星星的颜色 */
|
|
112
124
|
activeColor: {
|
|
113
125
|
type: String,
|
|
114
|
-
default:
|
|
126
|
+
default: "#FFF00D",
|
|
115
127
|
},
|
|
116
128
|
/** 星星之间的间距 */
|
|
117
129
|
gutter: {
|
|
@@ -149,54 +161,57 @@ const props = defineProps({
|
|
|
149
161
|
},
|
|
150
162
|
/** 自定义外部类名 */
|
|
151
163
|
customClass: String,
|
|
152
|
-
})
|
|
153
|
-
const
|
|
154
|
-
const emit = defineEmits<IRateEmits>()
|
|
164
|
+
});
|
|
165
|
+
const emit = defineEmits<IRateEmits>();
|
|
155
166
|
|
|
156
|
-
const elId = guid()
|
|
157
|
-
const elClass = guid()
|
|
158
|
-
const rateBoxLeft = ref<number>(0)
|
|
159
|
-
const activeIndex = ref(modelValue
|
|
167
|
+
const elId = guid();
|
|
168
|
+
const elClass = guid();
|
|
169
|
+
const rateBoxLeft = ref<number>(0);
|
|
170
|
+
const activeIndex = ref(props.modelValue);
|
|
160
171
|
// 每个星星的宽度
|
|
161
|
-
const rateWidth = ref(0)
|
|
172
|
+
const rateWidth = ref(0);
|
|
162
173
|
// 标识是否正在滑动,由于iOS事件上touch比click先触发,导致快速滑动结束后,接着触发click,导致事件混乱而出错
|
|
163
|
-
const moving = ref(false)
|
|
174
|
+
const moving = ref(false);
|
|
164
175
|
|
|
165
176
|
watch(
|
|
166
|
-
() => modelValue
|
|
177
|
+
() => props.modelValue,
|
|
167
178
|
(newValue) => {
|
|
168
|
-
activeIndex.value = newValue
|
|
179
|
+
activeIndex.value = newValue;
|
|
169
180
|
},
|
|
170
|
-
)
|
|
181
|
+
);
|
|
171
182
|
watch(
|
|
172
183
|
() => activeIndex.value,
|
|
173
|
-
(
|
|
174
|
-
emitEvent()
|
|
184
|
+
() => {
|
|
185
|
+
emitEvent();
|
|
175
186
|
},
|
|
176
|
-
)
|
|
177
|
-
const instance = getCurrentInstance()
|
|
187
|
+
);
|
|
188
|
+
const instance = getCurrentInstance();
|
|
178
189
|
|
|
179
190
|
onMounted(() => {
|
|
180
|
-
init()
|
|
181
|
-
})
|
|
191
|
+
init();
|
|
192
|
+
});
|
|
182
193
|
|
|
183
194
|
const init = () => {
|
|
184
195
|
sleep(300).then(async () => {
|
|
185
|
-
await getRateItemRect()
|
|
186
|
-
await getRateIconWrapRect()
|
|
187
|
-
})
|
|
188
|
-
}
|
|
196
|
+
await getRateItemRect();
|
|
197
|
+
await getRateIconWrapRect();
|
|
198
|
+
});
|
|
199
|
+
};
|
|
189
200
|
|
|
190
201
|
/**
|
|
191
202
|
* @description 获取评分组件盒子的布局信息
|
|
192
203
|
* */
|
|
193
204
|
const getRateItemRect = async () => {
|
|
194
|
-
await sleep()
|
|
205
|
+
await sleep();
|
|
195
206
|
// #ifndef APP-NVUE
|
|
196
|
-
const res: UniApp.NodeInfo = (await getRect(
|
|
197
|
-
|
|
207
|
+
const res: UniApp.NodeInfo = (await getRect(
|
|
208
|
+
`#${elId}`,
|
|
209
|
+
false,
|
|
210
|
+
instance,
|
|
211
|
+
)) as UniApp.NodeInfo;
|
|
212
|
+
rateBoxLeft.value = res.left || 0;
|
|
198
213
|
// #endif
|
|
199
|
-
}
|
|
214
|
+
};
|
|
200
215
|
|
|
201
216
|
/**
|
|
202
217
|
* @description 获取单个星星的尺寸
|
|
@@ -204,100 +219,104 @@ const getRateItemRect = async () => {
|
|
|
204
219
|
const getRateIconWrapRect = async () => {
|
|
205
220
|
// uView封装的获取节点的方法,详见文档
|
|
206
221
|
// #ifndef APP-NVUE
|
|
207
|
-
const res: UniApp.NodeInfo = (await getRect(
|
|
208
|
-
|
|
222
|
+
const res: UniApp.NodeInfo = (await getRect(
|
|
223
|
+
`.${elClass}`,
|
|
224
|
+
false,
|
|
225
|
+
instance,
|
|
226
|
+
)) as UniApp.NodeInfo;
|
|
227
|
+
rateWidth.value = res.width || 0;
|
|
209
228
|
// #endif
|
|
210
|
-
}
|
|
229
|
+
};
|
|
211
230
|
// 手指滑动
|
|
212
231
|
const touchMove = (e: TouchEvent) => {
|
|
213
232
|
// 如果禁止通过手动滑动选择,返回
|
|
214
|
-
if (!touchable
|
|
215
|
-
return
|
|
233
|
+
if (!props.touchable) {
|
|
234
|
+
return;
|
|
216
235
|
}
|
|
217
|
-
e.stopPropagation()
|
|
218
|
-
const x = e.changedTouches[0].pageX
|
|
219
|
-
getActiveIndex(x)
|
|
220
|
-
}
|
|
236
|
+
e.stopPropagation();
|
|
237
|
+
const x = e.changedTouches[0].pageX;
|
|
238
|
+
getActiveIndex(x);
|
|
239
|
+
};
|
|
221
240
|
// 停止滑动
|
|
222
241
|
const touchEnd = (e: TouchEvent) => {
|
|
223
242
|
// 如果禁止通过手动滑动选择,返回
|
|
224
|
-
if (!touchable
|
|
225
|
-
return
|
|
243
|
+
if (!props.touchable) {
|
|
244
|
+
return;
|
|
226
245
|
}
|
|
227
|
-
e.stopPropagation()
|
|
228
|
-
const x = e.changedTouches[0].pageX
|
|
229
|
-
getActiveIndex(x)
|
|
230
|
-
}
|
|
246
|
+
e.stopPropagation();
|
|
247
|
+
const x = e.changedTouches[0].pageX;
|
|
248
|
+
getActiveIndex(x);
|
|
249
|
+
};
|
|
231
250
|
// 通过点击,直接选中
|
|
232
251
|
const clickHandler = (e: TouchEvent) => {
|
|
233
252
|
// if (moving.value) {
|
|
234
253
|
// return;
|
|
235
254
|
// }
|
|
236
|
-
e.stopPropagation()
|
|
237
|
-
let x = 0
|
|
255
|
+
e.stopPropagation();
|
|
256
|
+
let x = 0;
|
|
238
257
|
// #ifndef APP-NVUE
|
|
239
|
-
x = e.changedTouches[0].pageX
|
|
258
|
+
x = e.changedTouches[0].pageX;
|
|
240
259
|
// #endif
|
|
241
|
-
getActiveIndex(x, true)
|
|
242
|
-
}
|
|
260
|
+
getActiveIndex(x, true);
|
|
261
|
+
};
|
|
243
262
|
// 发出事件
|
|
244
263
|
const emitEvent = () => {
|
|
245
264
|
// 发出change事件
|
|
246
|
-
emit(
|
|
265
|
+
emit("change", activeIndex.value);
|
|
247
266
|
// 同时修改双向绑定的值
|
|
248
|
-
emit(
|
|
249
|
-
}
|
|
267
|
+
emit("update:modelValue", activeIndex.value);
|
|
268
|
+
};
|
|
250
269
|
// 获取当前激活的评分图标
|
|
251
270
|
const getActiveIndex = (x: number, isClick = false) => {
|
|
252
|
-
if (disabled
|
|
253
|
-
return
|
|
271
|
+
if (props.disabled || props.readonly) {
|
|
272
|
+
return;
|
|
254
273
|
}
|
|
255
274
|
// 判断当前操作的点的x坐标值,是否在允许的边界范围内
|
|
256
|
-
const allRateWidth = rateWidth.value * count
|
|
275
|
+
const allRateWidth = rateWidth.value * props.count + rateBoxLeft.value;
|
|
257
276
|
// 如果小于第一个图标的左边界,设置为最小值,如果大于所有图标的宽度,则设置为最大值
|
|
258
|
-
x = range(rateBoxLeft.value, allRateWidth, x) - rateBoxLeft.value
|
|
277
|
+
x = range(rateBoxLeft.value, allRateWidth, x) - rateBoxLeft.value;
|
|
259
278
|
// 滑动点相对于评分盒子左边的距离
|
|
260
|
-
const distance = x
|
|
279
|
+
const distance = x;
|
|
261
280
|
// 滑动的距离,相当于多少颗星星
|
|
262
|
-
let index
|
|
281
|
+
let index;
|
|
263
282
|
// 判断是否允许半星
|
|
264
|
-
if (allowHalf
|
|
265
|
-
index = Math.floor(distance / rateWidth.value)
|
|
283
|
+
if (props.allowHalf) {
|
|
284
|
+
index = Math.floor(distance / rateWidth.value);
|
|
266
285
|
// 取余,判断小数的区间范围
|
|
267
|
-
const decimal = distance % rateWidth.value
|
|
286
|
+
const decimal = distance % rateWidth.value;
|
|
268
287
|
if (decimal <= rateWidth.value / 2 && decimal > 0) {
|
|
269
|
-
index += 0.5
|
|
288
|
+
index += 0.5;
|
|
270
289
|
} else if (decimal > rateWidth.value / 2) {
|
|
271
|
-
index
|
|
290
|
+
index++;
|
|
272
291
|
}
|
|
273
292
|
} else {
|
|
274
|
-
index = Math.floor(distance / rateWidth.value)
|
|
293
|
+
index = Math.floor(distance / rateWidth.value);
|
|
275
294
|
// 取余,判断小数的区间范围
|
|
276
|
-
const decimal = distance % rateWidth.value
|
|
295
|
+
const decimal = distance % rateWidth.value;
|
|
277
296
|
// 非半星时,只有超过了图标的一半距离,才认为是选择了这颗星
|
|
278
297
|
if (isClick) {
|
|
279
|
-
if (decimal > 0) index
|
|
298
|
+
if (decimal > 0) index++;
|
|
280
299
|
} else {
|
|
281
|
-
if (decimal > rateWidth.value / 2) index
|
|
300
|
+
if (decimal > rateWidth.value / 2) index++;
|
|
282
301
|
}
|
|
283
302
|
}
|
|
284
|
-
activeIndex.value = Math.min(index, count
|
|
303
|
+
activeIndex.value = Math.min(index, props.count);
|
|
285
304
|
// 对最少颗星星的限制
|
|
286
|
-
if (activeIndex.value < minCount
|
|
287
|
-
activeIndex.value = minCount
|
|
305
|
+
if (activeIndex.value < props.minCount) {
|
|
306
|
+
activeIndex.value = props.minCount;
|
|
288
307
|
}
|
|
289
308
|
|
|
290
309
|
// 设置延时为了让click事件在touchmove之前触发
|
|
291
310
|
setTimeout(() => {
|
|
292
|
-
moving.value = true
|
|
293
|
-
}, 10)
|
|
311
|
+
moving.value = true;
|
|
312
|
+
}, 10);
|
|
294
313
|
// 一定时间后,取消标识为移动中状态,是为了让click事件无效
|
|
295
314
|
setTimeout(() => {
|
|
296
|
-
moving.value = false
|
|
297
|
-
}, 10)
|
|
298
|
-
}
|
|
315
|
+
moving.value = false;
|
|
316
|
+
}, 10);
|
|
317
|
+
};
|
|
299
318
|
</script>
|
|
300
319
|
|
|
301
320
|
<style lang="scss" scoped>
|
|
302
|
-
@import
|
|
321
|
+
@import "./index.scss";
|
|
303
322
|
</style>
|
|
@@ -3,16 +3,26 @@
|
|
|
3
3
|
<view
|
|
4
4
|
class="hy-read-more__content"
|
|
5
5
|
:style="{
|
|
6
|
-
height:
|
|
6
|
+
height:
|
|
7
|
+
isLongContent && status === 'close'
|
|
8
|
+
? addUnit(showHeight)
|
|
9
|
+
: addUnit(contentHeight),
|
|
7
10
|
textIndent: textIndent,
|
|
8
11
|
}"
|
|
9
12
|
>
|
|
10
|
-
<view
|
|
13
|
+
<view
|
|
14
|
+
class="hy-read-more__content__inner"
|
|
15
|
+
ref="hy-read-more__content__inner"
|
|
16
|
+
:class="[elId]"
|
|
17
|
+
>
|
|
11
18
|
<slot></slot>
|
|
12
19
|
</view>
|
|
13
20
|
</view>
|
|
14
21
|
<view
|
|
15
|
-
:class="[
|
|
22
|
+
:class="[
|
|
23
|
+
'hy-read-more__toggle',
|
|
24
|
+
status !== 'open' && 'hy-read-more__toggle--mask',
|
|
25
|
+
]"
|
|
16
26
|
:style="[innerShadowStyle]"
|
|
17
27
|
v-if="isLongContent"
|
|
18
28
|
>
|
|
@@ -26,7 +36,7 @@
|
|
|
26
36
|
marginRight: '5px',
|
|
27
37
|
}"
|
|
28
38
|
>
|
|
29
|
-
{{ status ===
|
|
39
|
+
{{ status === "close" ? closeText : openText }}
|
|
30
40
|
</text>
|
|
31
41
|
<view class="hy-read-more__toggle__icon">
|
|
32
42
|
<HyIcon
|
|
@@ -43,36 +53,35 @@
|
|
|
43
53
|
|
|
44
54
|
<script lang="ts">
|
|
45
55
|
export default {
|
|
46
|
-
name:
|
|
56
|
+
name: "hy-read-more",
|
|
47
57
|
options: {
|
|
48
58
|
addGlobalClass: true,
|
|
49
59
|
virtualHost: true,
|
|
50
|
-
styleIsolation:
|
|
60
|
+
styleIsolation: "shared",
|
|
51
61
|
},
|
|
52
|
-
}
|
|
62
|
+
};
|
|
53
63
|
</script>
|
|
54
64
|
|
|
55
65
|
<script setup lang="ts">
|
|
56
|
-
import { computed,
|
|
57
|
-
import type { CSSProperties, PropType } from
|
|
58
|
-
import type { IReadMoreEmits } from
|
|
59
|
-
import { addUnit, getRect, guid, sleep } from
|
|
60
|
-
import { IconConfig } from
|
|
61
|
-
|
|
66
|
+
import { computed, ref, onMounted, getCurrentInstance } from "vue";
|
|
67
|
+
import type { CSSProperties, PropType } from "vue";
|
|
68
|
+
import type { IReadMoreEmits } from "./typing";
|
|
69
|
+
import { addUnit, getRect, guid, sleep } from "../../utils";
|
|
70
|
+
import { IconConfig } from "../../config";
|
|
62
71
|
// 组件
|
|
63
|
-
import HyIcon from
|
|
72
|
+
import HyIcon from "../hy-icon/hy-icon.vue";
|
|
64
73
|
|
|
65
74
|
/**
|
|
66
75
|
* 该组件一般用于内容较长,预先收起一部分,点击展开全部内容的场景。
|
|
67
76
|
* @displayName hy-read-more
|
|
68
77
|
*/
|
|
69
|
-
defineOptions({})
|
|
78
|
+
defineOptions({});
|
|
70
79
|
|
|
71
80
|
// const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
72
81
|
const props = defineProps({
|
|
73
82
|
/** 内容超出此高度才会显示展开全文按钮,单位px */
|
|
74
83
|
showHeight: {
|
|
75
|
-
type:
|
|
84
|
+
type: Number,
|
|
76
85
|
default: 200,
|
|
77
86
|
},
|
|
78
87
|
/** 展开后是否显示收起按钮 */
|
|
@@ -83,78 +92,84 @@ const props = defineProps({
|
|
|
83
92
|
/** 关闭时的提示文字 */
|
|
84
93
|
closeText: {
|
|
85
94
|
type: String,
|
|
86
|
-
default:
|
|
95
|
+
default: "展开阅读全文",
|
|
87
96
|
},
|
|
88
97
|
/** 展开时的提示文字 */
|
|
89
98
|
openText: {
|
|
90
99
|
type: String,
|
|
91
|
-
default:
|
|
100
|
+
default: "收起",
|
|
92
101
|
},
|
|
93
102
|
/** 提示文字的颜色 */
|
|
94
103
|
color: String,
|
|
95
104
|
/** 提示文字的大小,单位px */
|
|
96
105
|
fontSize: {
|
|
97
|
-
type:
|
|
106
|
+
type: Number,
|
|
98
107
|
default: 14,
|
|
99
108
|
},
|
|
100
109
|
/** 段落首行缩进的字符个数 */
|
|
101
110
|
textIndent: {
|
|
102
111
|
type: String,
|
|
103
|
-
default:
|
|
112
|
+
default: "2em",
|
|
104
113
|
},
|
|
105
114
|
/** 用于在 open 和 close 事件中当作回调参数返回 */
|
|
106
115
|
name: String,
|
|
107
116
|
/** 显示阴影的样式 */
|
|
108
|
-
shadowStyle:
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
117
|
+
shadowStyle: {
|
|
118
|
+
type: Object as PropType<CSSProperties>,
|
|
119
|
+
default: () => {},
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
const emit = defineEmits<IReadMoreEmits>();
|
|
112
123
|
|
|
113
|
-
const isLongContent = ref<boolean>(false) // 是否需要隐藏一部分内容
|
|
114
|
-
const status = ref<
|
|
115
|
-
const elId = ref<string>(guid()) // 生成唯一class
|
|
116
|
-
const contentHeight = ref<number>(100) // 内容高度
|
|
124
|
+
const isLongContent = ref<boolean>(false); // 是否需要隐藏一部分内容
|
|
125
|
+
const status = ref<"close" | "open">("close"); // 当前隐藏与显示的状态,close-收起状态,open-展开状态
|
|
126
|
+
const elId = ref<string>(guid()); // 生成唯一class
|
|
127
|
+
const contentHeight = ref<number>(100); // 内容高度
|
|
117
128
|
|
|
118
129
|
const innerShadowStyle = computed<CSSProperties>(() => {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
130
|
+
let style: CSSProperties = {};
|
|
131
|
+
|
|
132
|
+
if (status.value !== "open") {
|
|
133
|
+
style = props.shadowStyle;
|
|
134
|
+
}
|
|
135
|
+
return style;
|
|
136
|
+
});
|
|
122
137
|
|
|
123
138
|
onMounted(() => {
|
|
124
|
-
getContentHeight()
|
|
125
|
-
})
|
|
139
|
+
getContentHeight();
|
|
140
|
+
});
|
|
126
141
|
|
|
127
142
|
/**
|
|
128
143
|
* @description 获取内容的高度
|
|
129
144
|
* */
|
|
130
145
|
const getContentHeight = async () => {
|
|
131
|
-
const instance = getCurrentInstance()
|
|
146
|
+
const instance = getCurrentInstance();
|
|
132
147
|
// 延时一定时间再获取节点
|
|
133
|
-
await sleep(30)
|
|
134
|
-
getRect(
|
|
135
|
-
contentHeight.value = res.height || 0
|
|
148
|
+
await sleep(30);
|
|
149
|
+
getRect("." + elId.value, false, instance).then((res: any) => {
|
|
150
|
+
contentHeight.value = res.height || 0;
|
|
136
151
|
// 判断高度,如果真实内容高度大于占位高度,则显示收起与展开的控制按钮
|
|
137
|
-
if (res.height && res.height > showHeight
|
|
138
|
-
isLongContent.value = true
|
|
139
|
-
status.value =
|
|
152
|
+
if (res.height && res.height > props.showHeight / 2) {
|
|
153
|
+
isLongContent.value = true;
|
|
154
|
+
status.value = "close";
|
|
140
155
|
} else {
|
|
141
|
-
isLongContent.value = false
|
|
142
|
-
status.value =
|
|
156
|
+
isLongContent.value = false;
|
|
157
|
+
status.value = "close";
|
|
143
158
|
}
|
|
144
|
-
})
|
|
145
|
-
}
|
|
159
|
+
});
|
|
160
|
+
};
|
|
146
161
|
/**
|
|
147
162
|
* @description 展开或者收起
|
|
148
163
|
* */
|
|
149
164
|
const toggleReadMore = () => {
|
|
150
|
-
status.value = status.value ===
|
|
165
|
+
status.value = status.value === "close" ? "open" : "close";
|
|
151
166
|
// 如果toggle为false,隐藏"收起"部分的内容
|
|
152
|
-
if (!toggle
|
|
167
|
+
if (!props.toggle) isLongContent.value = false;
|
|
153
168
|
// 发出打开或者收齐的事件
|
|
154
|
-
emit(status.value, name
|
|
155
|
-
}
|
|
169
|
+
emit(status.value, props.name);
|
|
170
|
+
};
|
|
156
171
|
</script>
|
|
157
172
|
|
|
158
173
|
<style lang="scss" scoped>
|
|
159
|
-
@import
|
|
174
|
+
@import "./index.scss";
|
|
160
175
|
</style>
|
|
@@ -33,25 +33,26 @@
|
|
|
33
33
|
|
|
34
34
|
<script lang="ts">
|
|
35
35
|
export default {
|
|
36
|
-
name:
|
|
36
|
+
name: "hy-scroll-list",
|
|
37
37
|
options: {
|
|
38
38
|
addGlobalClass: true,
|
|
39
39
|
virtualHost: true,
|
|
40
|
-
styleIsolation:
|
|
40
|
+
styleIsolation: "shared",
|
|
41
41
|
},
|
|
42
|
-
}
|
|
42
|
+
};
|
|
43
43
|
</script>
|
|
44
44
|
|
|
45
45
|
<script setup lang="ts">
|
|
46
|
-
import { computed,
|
|
47
|
-
import type {
|
|
48
|
-
import {
|
|
46
|
+
import { computed, ref, onMounted, getCurrentInstance } from "vue";
|
|
47
|
+
import type { CSSProperties } from "vue";
|
|
48
|
+
import type { IScrollListEmits } from "./typing";
|
|
49
|
+
import { addUnit, colorGradient, getRect, sleep } from "../../utils";
|
|
49
50
|
|
|
50
51
|
/**
|
|
51
52
|
* 该组件一般用于同时展示多个商品、分类的场景,也可以完成左右滑动的列表。
|
|
52
53
|
* @displayName hy-scroll-list
|
|
53
54
|
*/
|
|
54
|
-
defineOptions({})
|
|
55
|
+
defineOptions({});
|
|
55
56
|
|
|
56
57
|
// const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
57
58
|
const props = defineProps({
|
|
@@ -74,77 +75,73 @@ const props = defineProps({
|
|
|
74
75
|
indicatorColor: String,
|
|
75
76
|
/** 指示器的激活颜色 */
|
|
76
77
|
indicatorActiveColor: String,
|
|
77
|
-
})
|
|
78
|
-
const
|
|
79
|
-
const emit = defineEmits<IScrollListEmits>()
|
|
78
|
+
});
|
|
79
|
+
const emit = defineEmits<IScrollListEmits>();
|
|
80
80
|
|
|
81
|
-
const instance = getCurrentInstance()
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
scrollWidth: 0,
|
|
85
|
-
})
|
|
86
|
-
const scrollWidth = ref(0)
|
|
87
|
-
const barLeft = ref(0)
|
|
81
|
+
const instance = getCurrentInstance();
|
|
82
|
+
const scrollWidth = ref(0);
|
|
83
|
+
const barLeft = ref(0);
|
|
88
84
|
|
|
89
85
|
/**
|
|
90
86
|
* @description 线条样式
|
|
91
87
|
* */
|
|
92
88
|
const barStyle = computed<CSSProperties>(() => {
|
|
93
|
-
const style: CSSProperties = {}
|
|
94
|
-
style.transform = `translateX(${barLeft.value}px)
|
|
89
|
+
const style: CSSProperties = {};
|
|
90
|
+
style.transform = `translateX(${barLeft.value}px)`;
|
|
95
91
|
// 设置滑块的宽度和背景色,是每个平台都需要的
|
|
96
|
-
style.width = addUnit(indicatorBarWidth
|
|
97
|
-
style.backgroundColor = indicatorActiveColor
|
|
98
|
-
return style
|
|
99
|
-
})
|
|
92
|
+
style.width = addUnit(props.indicatorBarWidth);
|
|
93
|
+
style.backgroundColor = props.indicatorActiveColor;
|
|
94
|
+
return style;
|
|
95
|
+
});
|
|
100
96
|
/**
|
|
101
97
|
* @description 轨道样式
|
|
102
98
|
* */
|
|
103
99
|
const lineStyle = computed<CSSProperties>(() => {
|
|
104
|
-
const style: CSSProperties = {}
|
|
100
|
+
const style: CSSProperties = {};
|
|
105
101
|
// 指示器整体的样式,需要设置其宽度和背景色
|
|
106
|
-
style.width = addUnit(indicatorWidth
|
|
102
|
+
style.width = addUnit(props.indicatorWidth);
|
|
107
103
|
style.backgroundColor =
|
|
108
|
-
indicatorColor
|
|
109
|
-
(indicatorActiveColor
|
|
110
|
-
|
|
111
|
-
|
|
104
|
+
props.indicatorColor ||
|
|
105
|
+
(props.indicatorActiveColor &&
|
|
106
|
+
colorGradient(props.indicatorActiveColor)[90]);
|
|
107
|
+
return style;
|
|
108
|
+
});
|
|
112
109
|
|
|
113
110
|
onMounted(() => {
|
|
114
|
-
initWidth()
|
|
115
|
-
})
|
|
111
|
+
initWidth();
|
|
112
|
+
});
|
|
116
113
|
|
|
117
114
|
/**
|
|
118
115
|
* @description 初始化宽度
|
|
119
116
|
* */
|
|
120
117
|
const initWidth = async () => {
|
|
121
118
|
// 延时一定时间,以获取dom尺寸
|
|
122
|
-
await sleep(30)
|
|
119
|
+
await sleep(30);
|
|
123
120
|
// #ifndef APP-NVUE
|
|
124
|
-
getRect(
|
|
125
|
-
scrollWidth.value = (size as UniApp.NodeInfo).width
|
|
126
|
-
})
|
|
121
|
+
getRect(".hy-scroll-list", false, instance).then((size) => {
|
|
122
|
+
scrollWidth.value = (size as UniApp.NodeInfo).width!;
|
|
123
|
+
});
|
|
127
124
|
// #endif
|
|
128
|
-
}
|
|
125
|
+
};
|
|
129
126
|
|
|
130
127
|
const onScroll = (event: any) => {
|
|
131
|
-
const { scrollLeft, scrollWidth: totalWidth } = event.detail
|
|
132
|
-
const targetWidth = totalWidth - scrollWidth.value
|
|
133
|
-
const targetBarWidth = indicatorWidth
|
|
134
|
-
barLeft.value = (scrollLeft / targetWidth) * targetBarWidth
|
|
135
|
-
}
|
|
128
|
+
const { scrollLeft, scrollWidth: totalWidth } = event.detail;
|
|
129
|
+
const targetWidth = totalWidth - scrollWidth.value;
|
|
130
|
+
const targetBarWidth = props.indicatorWidth - props.indicatorBarWidth;
|
|
131
|
+
barLeft.value = (scrollLeft / targetWidth) * targetBarWidth;
|
|
132
|
+
};
|
|
136
133
|
|
|
137
134
|
const onScrollToLower = () => {
|
|
138
|
-
barLeft.value = indicatorWidth
|
|
139
|
-
emit(
|
|
140
|
-
}
|
|
135
|
+
barLeft.value = props.indicatorWidth - props.indicatorBarWidth;
|
|
136
|
+
emit("scrollRight");
|
|
137
|
+
};
|
|
141
138
|
|
|
142
139
|
const onScrollToUpper = () => {
|
|
143
|
-
barLeft.value = 0
|
|
144
|
-
emit(
|
|
145
|
-
}
|
|
140
|
+
barLeft.value = 0;
|
|
141
|
+
emit("scrollLeft");
|
|
142
|
+
};
|
|
146
143
|
</script>
|
|
147
144
|
|
|
148
145
|
<style lang="scss" scoped>
|
|
149
|
-
@import
|
|
146
|
+
@import "./index.scss";
|
|
150
147
|
</style>
|