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
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
:style="{
|
|
17
17
|
color: color,
|
|
18
18
|
backgroundColor:
|
|
19
|
-
bgColor && showTooltip && tooltipTop !== -10000
|
|
19
|
+
bgColor && showTooltip && tooltipTop !== -10000
|
|
20
|
+
? bgColor
|
|
21
|
+
: 'transparent',
|
|
20
22
|
}"
|
|
21
23
|
>
|
|
22
24
|
{{ text }}
|
|
@@ -32,7 +34,11 @@
|
|
|
32
34
|
...tooltipStyle,
|
|
33
35
|
}"
|
|
34
36
|
>
|
|
35
|
-
<view
|
|
37
|
+
<view
|
|
38
|
+
class="hy-tooltip__wrapper__popup"
|
|
39
|
+
:id="tooltipId"
|
|
40
|
+
:ref="tooltipId"
|
|
41
|
+
>
|
|
36
42
|
<view
|
|
37
43
|
v-if="showCopy || buttons.length"
|
|
38
44
|
class="hy-tooltip__wrapper__popup__indicator"
|
|
@@ -54,7 +60,9 @@
|
|
|
54
60
|
hover-class="hy-tooltip__wrapper__popup__list__btn--hover"
|
|
55
61
|
@tap="setClipboardData"
|
|
56
62
|
>
|
|
57
|
-
<text class="hy-tooltip__wrapper__popup__list__btn__text"
|
|
63
|
+
<text class="hy-tooltip__wrapper__popup__list__btn__text"
|
|
64
|
+
>复制</text
|
|
65
|
+
>
|
|
58
66
|
</view>
|
|
59
67
|
<HyLine
|
|
60
68
|
direction="column"
|
|
@@ -62,7 +70,7 @@
|
|
|
62
70
|
v-if="showCopy && buttons.length > 0"
|
|
63
71
|
length="18"
|
|
64
72
|
></HyLine>
|
|
65
|
-
<
|
|
73
|
+
<template v-for="(item, index) in buttons" :key="index">
|
|
66
74
|
<view
|
|
67
75
|
class="hy-tooltip__wrapper__popup__list__btn"
|
|
68
76
|
hover-class="hy-tooltip__wrapper__popup__list__btn--hover"
|
|
@@ -80,7 +88,7 @@
|
|
|
80
88
|
v-if="index < buttons.length - 1"
|
|
81
89
|
length="18"
|
|
82
90
|
></HyLine>
|
|
83
|
-
</
|
|
91
|
+
</template>
|
|
84
92
|
</view>
|
|
85
93
|
</view>
|
|
86
94
|
</HyTransition>
|
|
@@ -90,38 +98,44 @@
|
|
|
90
98
|
|
|
91
99
|
<script lang="ts">
|
|
92
100
|
export default {
|
|
93
|
-
name:
|
|
101
|
+
name: "hy-tooltip",
|
|
94
102
|
options: {
|
|
95
103
|
addGlobalClass: true,
|
|
96
104
|
virtualHost: true,
|
|
97
|
-
styleIsolation:
|
|
105
|
+
styleIsolation: "shared",
|
|
98
106
|
},
|
|
99
|
-
}
|
|
107
|
+
};
|
|
100
108
|
</script>
|
|
101
109
|
|
|
102
110
|
<script setup lang="ts">
|
|
103
|
-
import { computed,
|
|
104
|
-
import type { CSSProperties, PropType } from
|
|
105
|
-
import type { ITooltipEmits } from
|
|
106
|
-
import { addUnit, getRect, guid, sleep } from
|
|
111
|
+
import { computed, ref, onMounted, getCurrentInstance } from "vue";
|
|
112
|
+
import type { CSSProperties, PropType } from "vue";
|
|
113
|
+
import type { ITooltipEmits } from "./typing";
|
|
114
|
+
import { addUnit, getRect, guid, sleep } from "../../utils";
|
|
107
115
|
|
|
108
116
|
// 组件
|
|
109
|
-
import HyOverlay from
|
|
110
|
-
import HyTransition from
|
|
111
|
-
import HyLine from
|
|
117
|
+
import HyOverlay from "../hy-overlay/hy-overlay.vue";
|
|
118
|
+
import HyTransition from "../hy-transition/hy-transition.vue";
|
|
119
|
+
import HyLine from "../hy-line/hy-line.vue";
|
|
112
120
|
|
|
113
121
|
/**
|
|
114
122
|
* Tooltip组件主要用于长按操作,类似微信的长按气泡
|
|
115
123
|
* @displayName hy-tooltip
|
|
116
124
|
*/
|
|
117
|
-
defineOptions({})
|
|
125
|
+
defineOptions({});
|
|
118
126
|
|
|
119
127
|
// const props = withDefaults(defineProps<IProps>(), defaultProps);
|
|
120
128
|
const props = defineProps({
|
|
121
129
|
/** 需要显示的提示文字 */
|
|
122
|
-
text:
|
|
130
|
+
text: {
|
|
131
|
+
type: String,
|
|
132
|
+
default: "",
|
|
133
|
+
},
|
|
123
134
|
/** 点击复制按钮时,复制的文本,为空则使用text值 */
|
|
124
|
-
copyText:
|
|
135
|
+
copyText: {
|
|
136
|
+
type: String,
|
|
137
|
+
default: "",
|
|
138
|
+
},
|
|
125
139
|
/** 文本大小 */
|
|
126
140
|
size: {
|
|
127
141
|
type: [String, Number],
|
|
@@ -132,7 +146,7 @@ const props = defineProps({
|
|
|
132
146
|
/** 弹出提示框时,文本的背景色 */
|
|
133
147
|
bgColor: {
|
|
134
148
|
type: String,
|
|
135
|
-
default:
|
|
149
|
+
default: "transparent",
|
|
136
150
|
},
|
|
137
151
|
/**
|
|
138
152
|
* 弹出提示的方向
|
|
@@ -140,7 +154,7 @@ const props = defineProps({
|
|
|
140
154
|
* */
|
|
141
155
|
direction: {
|
|
142
156
|
type: String,
|
|
143
|
-
default:
|
|
157
|
+
default: "top",
|
|
144
158
|
},
|
|
145
159
|
/** 弹出提示的z-index,nvue无效 */
|
|
146
160
|
zIndex: {
|
|
@@ -156,7 +170,7 @@ const props = defineProps({
|
|
|
156
170
|
buttons: {
|
|
157
171
|
type: Array,
|
|
158
172
|
default() {
|
|
159
|
-
return []
|
|
173
|
+
return [];
|
|
160
174
|
},
|
|
161
175
|
},
|
|
162
176
|
/** 是否显示透明遮罩以防止触摸穿透 */
|
|
@@ -173,156 +187,160 @@ const props = defineProps({
|
|
|
173
187
|
customStyle: Object as PropType<CSSProperties>,
|
|
174
188
|
/** 自定义外部类名 */
|
|
175
189
|
customClass: String,
|
|
176
|
-
})
|
|
177
|
-
const
|
|
178
|
-
const emit = defineEmits<ITooltipEmits>()
|
|
190
|
+
});
|
|
191
|
+
const emit = defineEmits<ITooltipEmits>();
|
|
179
192
|
|
|
180
|
-
const instance = getCurrentInstance()
|
|
181
|
-
const showTooltip = ref<boolean>(true)
|
|
182
|
-
const textId = ref(guid())
|
|
183
|
-
const tooltipId = ref(guid())
|
|
184
|
-
const tooltipTop = ref<number>(-10000)
|
|
193
|
+
const instance = getCurrentInstance();
|
|
194
|
+
const showTooltip = ref<boolean>(true);
|
|
195
|
+
const textId = ref(guid());
|
|
196
|
+
const tooltipId = ref(guid());
|
|
197
|
+
const tooltipTop = ref<number>(-10000);
|
|
185
198
|
// 气泡的位置信息
|
|
186
199
|
const tooltipInfo = ref<UniApp.NodeInfo>({
|
|
187
200
|
width: 0,
|
|
188
201
|
left: 0,
|
|
189
|
-
})
|
|
202
|
+
});
|
|
190
203
|
const textInfo = ref<UniApp.NodeInfo>({
|
|
191
204
|
width: 0,
|
|
192
205
|
left: 0,
|
|
193
206
|
right: 0,
|
|
194
|
-
})
|
|
207
|
+
});
|
|
195
208
|
// 三角形指示器的样式
|
|
196
209
|
const indicatorStyle = ref<CSSProperties>({
|
|
197
210
|
left: 0,
|
|
198
211
|
right: 0,
|
|
199
|
-
})
|
|
212
|
+
});
|
|
200
213
|
// 气泡在可能超出屏幕边沿范围时,重新定位后,距离屏幕边沿的距离
|
|
201
|
-
const screenGap = ref(12)
|
|
214
|
+
const screenGap = ref(12);
|
|
202
215
|
// 三角形指示器的宽高,由于对元素进行了角度旋转,精确计算指示器位置时,需要用到其尺寸信息
|
|
203
|
-
const indicatorWidth = ref(14)
|
|
216
|
+
const indicatorWidth = ref(14);
|
|
204
217
|
|
|
205
|
-
// 特别处理H5的复制,因为H5浏览器是自带系统复制功能的,在H5环境
|
|
206
|
-
// 当一些依赖参数变化时,需要重新计算气泡和指示器的位置信息
|
|
207
|
-
const propsChange = computed(() => {
|
|
208
|
-
return [text.value, buttons.value]
|
|
209
|
-
})
|
|
210
218
|
// 计算气泡和指示器的位置信息
|
|
211
219
|
const tooltipStyle = computed(() => {
|
|
212
220
|
const style: CSSProperties = {
|
|
213
|
-
transform: `translateY(${direction
|
|
221
|
+
transform: `translateY(${props.direction === "top" ? "-100%" : "100%"})`,
|
|
214
222
|
},
|
|
215
223
|
// #ifdef APP || H5 || MP-WEIXIN
|
|
216
|
-
sysInfo = uni.getWindowInfo()
|
|
224
|
+
sysInfo = uni.getWindowInfo();
|
|
217
225
|
// #endif
|
|
218
226
|
if (
|
|
219
227
|
tooltipInfo.value.width! / 2 >
|
|
220
228
|
textInfo.value.left! + textInfo.value.width! / 2 - screenGap.value
|
|
221
229
|
) {
|
|
222
|
-
indicatorStyle.value = {}
|
|
223
|
-
style.left = `-${addUnit(textInfo.value.left! - screenGap.value)}
|
|
230
|
+
indicatorStyle.value = {};
|
|
231
|
+
style.left = `-${addUnit(textInfo.value.left! - screenGap.value)}`;
|
|
224
232
|
indicatorStyle.value.left = addUnit(
|
|
225
233
|
textInfo.value.width! / 2 - Number(style.left) - indicatorWidth.value / 2,
|
|
226
|
-
)
|
|
234
|
+
);
|
|
227
235
|
} else if (
|
|
228
236
|
tooltipInfo.value.width! / 2 >
|
|
229
|
-
sysInfo.windowWidth -
|
|
237
|
+
sysInfo.windowWidth -
|
|
238
|
+
textInfo.value.right! +
|
|
239
|
+
textInfo.value.width! / 2 -
|
|
240
|
+
screenGap.value
|
|
230
241
|
) {
|
|
231
|
-
indicatorStyle.value = {}
|
|
232
|
-
style.right = `-${addUnit(sysInfo.windowWidth - textInfo.value.right! - screenGap.value)}
|
|
242
|
+
indicatorStyle.value = {};
|
|
243
|
+
style.right = `-${addUnit(sysInfo.windowWidth - textInfo.value.right! - screenGap.value)}`;
|
|
233
244
|
indicatorStyle.value.right = addUnit(
|
|
234
|
-
textInfo.value.width! / 2 -
|
|
235
|
-
|
|
245
|
+
textInfo.value.width! / 2 -
|
|
246
|
+
Number(style.right) -
|
|
247
|
+
indicatorWidth.value / 2,
|
|
248
|
+
);
|
|
236
249
|
} else {
|
|
237
|
-
const left = Math.abs(
|
|
238
|
-
|
|
239
|
-
|
|
250
|
+
const left = Math.abs(
|
|
251
|
+
textInfo.value.width! / 2 - tooltipInfo.value.width! / 2,
|
|
252
|
+
);
|
|
253
|
+
style.left =
|
|
254
|
+
textInfo.value.width! > tooltipInfo.value.width!
|
|
255
|
+
? addUnit(left)
|
|
256
|
+
: -addUnit(left);
|
|
257
|
+
indicatorStyle.value = {};
|
|
240
258
|
}
|
|
241
|
-
if (direction
|
|
242
|
-
style.marginTop =
|
|
243
|
-
indicatorStyle.value.bottom =
|
|
259
|
+
if (props.direction === "top") {
|
|
260
|
+
style.marginTop = "-10px";
|
|
261
|
+
indicatorStyle.value.bottom = "-4px";
|
|
244
262
|
} else {
|
|
245
|
-
style.marginBottom =
|
|
246
|
-
indicatorStyle.value.top =
|
|
263
|
+
style.marginBottom = "-10px";
|
|
264
|
+
indicatorStyle.value.top = "-4px";
|
|
247
265
|
}
|
|
248
|
-
return style
|
|
249
|
-
})
|
|
266
|
+
return style;
|
|
267
|
+
});
|
|
250
268
|
|
|
251
269
|
onMounted(() => {
|
|
252
|
-
getElRect()
|
|
253
|
-
})
|
|
270
|
+
getElRect();
|
|
271
|
+
});
|
|
254
272
|
|
|
255
273
|
/**
|
|
256
274
|
* @description 长按触发事件
|
|
257
275
|
* */
|
|
258
276
|
const longPressHandler = () => {
|
|
259
|
-
tooltipTop.value = 0
|
|
260
|
-
showTooltip.value = true
|
|
261
|
-
}
|
|
277
|
+
tooltipTop.value = 0;
|
|
278
|
+
showTooltip.value = true;
|
|
279
|
+
};
|
|
262
280
|
|
|
263
281
|
/**
|
|
264
282
|
* @description 点击透明遮罩
|
|
265
283
|
* */
|
|
266
284
|
const overlayClickHandler = () => {
|
|
267
|
-
showTooltip.value = false
|
|
268
|
-
}
|
|
285
|
+
showTooltip.value = false;
|
|
286
|
+
};
|
|
269
287
|
|
|
270
288
|
/**
|
|
271
289
|
* @description 点击弹出按钮
|
|
272
290
|
* */
|
|
273
291
|
const btnClickHandler = (index: number) => {
|
|
274
|
-
showTooltip.value = false
|
|
292
|
+
showTooltip.value = false;
|
|
275
293
|
// 如果需要展示复制按钮,此处index需要加1,因为复制按钮在第一个位置
|
|
276
|
-
emit(
|
|
277
|
-
}
|
|
294
|
+
emit("click", props.showCopy ? index + 1 : index);
|
|
295
|
+
};
|
|
278
296
|
|
|
279
297
|
/**
|
|
280
298
|
* @description 元素尺寸
|
|
281
299
|
* */
|
|
282
300
|
const getElRect = () => {
|
|
283
301
|
// 调用之前,先将指示器调整到屏幕外,方便获取尺寸
|
|
284
|
-
showTooltip.value = true
|
|
285
|
-
tooltipTop.value = -10000
|
|
302
|
+
showTooltip.value = true;
|
|
303
|
+
tooltipTop.value = -10000;
|
|
286
304
|
sleep(500).then(() => {
|
|
287
305
|
getRect(`#${tooltipId.value}`, false, instance).then((size) => {
|
|
288
|
-
tooltipInfo.value = size as UniApp.NodeInfo
|
|
306
|
+
tooltipInfo.value = size as UniApp.NodeInfo;
|
|
289
307
|
// 获取气泡尺寸之后,将其隐藏,为了让下次切换气泡显示与隐藏时,有淡入淡出的效果
|
|
290
|
-
showTooltip.value = false
|
|
291
|
-
})
|
|
308
|
+
showTooltip.value = false;
|
|
309
|
+
});
|
|
292
310
|
getRect(`#${textId.value}`, false, instance).then((size) => {
|
|
293
|
-
textInfo.value = size as UniApp.NodeInfo
|
|
294
|
-
})
|
|
295
|
-
})
|
|
296
|
-
}
|
|
311
|
+
textInfo.value = size as UniApp.NodeInfo;
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
};
|
|
297
315
|
/**
|
|
298
316
|
* @description 复制文本到粘贴板
|
|
299
317
|
* */
|
|
300
318
|
const setClipboardData = () => {
|
|
301
319
|
// 关闭组件
|
|
302
|
-
showTooltip.value = false
|
|
303
|
-
emit(
|
|
320
|
+
showTooltip.value = false;
|
|
321
|
+
emit("click", 0);
|
|
304
322
|
uni.setClipboardData({
|
|
305
323
|
// 优先使用copyText字段,如果没有,则默认使用text字段当做复制的内容
|
|
306
|
-
data: copyText
|
|
324
|
+
data: props.copyText || props.text,
|
|
307
325
|
success: () => {
|
|
308
|
-
showToast
|
|
326
|
+
props.showToast &&
|
|
309
327
|
uni.showToast({
|
|
310
|
-
title:
|
|
311
|
-
})
|
|
328
|
+
title: "复制成功",
|
|
329
|
+
});
|
|
312
330
|
},
|
|
313
331
|
fail: () => {
|
|
314
|
-
showToast
|
|
332
|
+
props.showToast &&
|
|
315
333
|
uni.showToast({
|
|
316
|
-
title:
|
|
317
|
-
})
|
|
334
|
+
title: "复制失败",
|
|
335
|
+
});
|
|
318
336
|
},
|
|
319
337
|
complete: () => {
|
|
320
|
-
showTooltip.value = false
|
|
338
|
+
showTooltip.value = false;
|
|
321
339
|
},
|
|
322
|
-
})
|
|
323
|
-
}
|
|
340
|
+
});
|
|
341
|
+
};
|
|
324
342
|
</script>
|
|
325
343
|
|
|
326
344
|
<style lang="scss" scoped>
|
|
327
|
-
@import
|
|
345
|
+
@import "./index.scss";
|
|
328
346
|
</style>
|
|
@@ -13,26 +13,26 @@
|
|
|
13
13
|
|
|
14
14
|
<script lang="ts">
|
|
15
15
|
export default {
|
|
16
|
-
name:
|
|
16
|
+
name: "hy-transition",
|
|
17
17
|
options: {
|
|
18
18
|
addGlobalClass: true,
|
|
19
19
|
virtualHost: true,
|
|
20
|
-
styleIsolation:
|
|
20
|
+
styleIsolation: "shared",
|
|
21
21
|
},
|
|
22
|
-
}
|
|
22
|
+
};
|
|
23
23
|
</script>
|
|
24
24
|
|
|
25
25
|
<script setup lang="ts">
|
|
26
|
-
import { computed, ref, watch, nextTick
|
|
27
|
-
import type { CSSProperties, PropType } from
|
|
28
|
-
import { sleep } from
|
|
29
|
-
import type { ITransitionEmits } from
|
|
26
|
+
import { computed, ref, watch, nextTick } from "vue";
|
|
27
|
+
import type { CSSProperties, PropType } from "vue";
|
|
28
|
+
import { sleep } from "../../utils";
|
|
29
|
+
import type { ITransitionEmits } from "./typing";
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* 该组件用于组件的动画过渡效果。
|
|
33
33
|
* @displayName hy-transition
|
|
34
34
|
*/
|
|
35
|
-
defineOptions({})
|
|
35
|
+
defineOptions({});
|
|
36
36
|
|
|
37
37
|
// const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
38
38
|
const props = defineProps({
|
|
@@ -44,7 +44,7 @@ const props = defineProps({
|
|
|
44
44
|
/** 使用的动画模式 */
|
|
45
45
|
mode: {
|
|
46
46
|
type: String,
|
|
47
|
-
default:
|
|
47
|
+
default: "fade",
|
|
48
48
|
},
|
|
49
49
|
/** 动画的执行时间,单位ms */
|
|
50
50
|
duration: {
|
|
@@ -54,7 +54,7 @@ const props = defineProps({
|
|
|
54
54
|
/** 使用的动画过渡函数 */
|
|
55
55
|
timingFunction: {
|
|
56
56
|
type: String,
|
|
57
|
-
default:
|
|
57
|
+
default: "ease-out",
|
|
58
58
|
},
|
|
59
59
|
/** 定义需要用到的外部样式 */
|
|
60
60
|
customStyle: {
|
|
@@ -62,72 +62,71 @@ const props = defineProps({
|
|
|
62
62
|
},
|
|
63
63
|
/** 自定义外部类名 */
|
|
64
64
|
customClass: String,
|
|
65
|
-
})
|
|
66
|
-
const
|
|
67
|
-
const emit = defineEmits<ITransitionEmits>()
|
|
65
|
+
});
|
|
66
|
+
const emit = defineEmits<ITransitionEmits>();
|
|
68
67
|
|
|
69
|
-
const hasInit = ref<boolean>(false) // 是否显示/隐藏组件
|
|
70
|
-
const viewStyle = ref<CSSProperties>({}) // 组件内部的样式
|
|
71
|
-
const status = ref<string>(
|
|
72
|
-
const transitionEnded = ref<boolean>(false) // 组件是否结束的标记
|
|
73
|
-
const display = ref<boolean>(false) // 组件是否展示
|
|
74
|
-
const classes = ref<string>(
|
|
68
|
+
const hasInit = ref<boolean>(false); // 是否显示/隐藏组件
|
|
69
|
+
const viewStyle = ref<CSSProperties>({}); // 组件内部的样式
|
|
70
|
+
const status = ref<string>(""); // 记录组件动画的状态
|
|
71
|
+
const transitionEnded = ref<boolean>(false); // 组件是否结束的标记
|
|
72
|
+
const display = ref<boolean>(false); // 组件是否展示
|
|
73
|
+
const classes = ref<string>(""); // 应用的类名
|
|
75
74
|
|
|
76
75
|
// #ifndef APP-NVUE
|
|
77
76
|
// 定义类名,通过给元素动态切换类名,赋予元素一定的css动画样式
|
|
78
77
|
const getClassNames = (name: string) => ({
|
|
79
78
|
enter: `u-${name}-enter u-${name}-enter-active`,
|
|
80
|
-
|
|
79
|
+
"enter-to": `u-${name}-enter-to u-${name}-enter-active`,
|
|
81
80
|
leave: `u-${name}-leave u-${name}-leave-active`,
|
|
82
|
-
|
|
83
|
-
})
|
|
81
|
+
"leave-to": `u-${name}-leave-to u-${name}-leave-active`,
|
|
82
|
+
});
|
|
84
83
|
// #endif
|
|
85
84
|
|
|
86
85
|
// #ifndef APP-NVUE
|
|
87
86
|
// vue版本的组件进场处理
|
|
88
87
|
const vueEnter = async () => {
|
|
89
88
|
// 动画进入时的类名
|
|
90
|
-
const classNames = getClassNames(mode
|
|
89
|
+
const classNames = getClassNames(props.mode);
|
|
91
90
|
// 定义状态和发出动画进入前事件
|
|
92
|
-
status.value =
|
|
93
|
-
emit(
|
|
94
|
-
hasInit.value = true
|
|
95
|
-
display.value = true
|
|
96
|
-
classes.value = classNames.enter
|
|
97
|
-
await nextTick()
|
|
91
|
+
status.value = "enter";
|
|
92
|
+
emit("beforeEnter");
|
|
93
|
+
hasInit.value = true;
|
|
94
|
+
display.value = true;
|
|
95
|
+
classes.value = classNames.enter;
|
|
96
|
+
await nextTick();
|
|
98
97
|
{
|
|
99
98
|
// https://github.com/umicro/uView2.0/issues/545
|
|
100
|
-
await sleep(20)
|
|
99
|
+
await sleep(20);
|
|
101
100
|
// 标识动画尚未结束
|
|
102
|
-
emit(
|
|
103
|
-
transitionEnded.value = false
|
|
101
|
+
emit("enter");
|
|
102
|
+
transitionEnded.value = false;
|
|
104
103
|
// 组件动画进入后触发的事件
|
|
105
|
-
emit(
|
|
104
|
+
emit("afterEnter");
|
|
106
105
|
// 赋予组件enter-to类名
|
|
107
|
-
classes.value = classNames[
|
|
106
|
+
classes.value = classNames["enter-to"];
|
|
108
107
|
}
|
|
109
|
-
}
|
|
108
|
+
};
|
|
110
109
|
// 动画离场处理
|
|
111
110
|
const vueLeave = async () => {
|
|
112
111
|
// 如果不是展示状态,无需执行逻辑
|
|
113
|
-
if (!display.value) return
|
|
114
|
-
const classNames = getClassNames(mode
|
|
112
|
+
if (!display.value) return;
|
|
113
|
+
const classNames = getClassNames(props.mode);
|
|
115
114
|
// 标记离开状态和发出事件
|
|
116
|
-
status.value =
|
|
117
|
-
emit(
|
|
115
|
+
status.value = "leave";
|
|
116
|
+
emit("beforeLeave");
|
|
118
117
|
// 获得类名
|
|
119
|
-
classes.value = classNames.leave
|
|
118
|
+
classes.value = classNames.leave;
|
|
120
119
|
|
|
121
|
-
await nextTick()
|
|
120
|
+
await nextTick();
|
|
122
121
|
{
|
|
123
122
|
// 动画正在离场的状态
|
|
124
|
-
transitionEnded.value = false
|
|
125
|
-
emit(
|
|
123
|
+
transitionEnded.value = false;
|
|
124
|
+
emit("leave");
|
|
126
125
|
// 组件执行动画,到了执行的执行时间后,执行一些额外处理
|
|
127
|
-
setTimeout(() => onTransitionEnd(), duration
|
|
128
|
-
classes.value = classNames[
|
|
126
|
+
setTimeout(() => onTransitionEnd(), props.duration);
|
|
127
|
+
classes.value = classNames["leave-to"];
|
|
129
128
|
}
|
|
130
|
-
}
|
|
129
|
+
};
|
|
131
130
|
// #endif
|
|
132
131
|
|
|
133
132
|
watch(
|
|
@@ -138,51 +137,48 @@ watch(
|
|
|
138
137
|
// newVal ? nvueEnter() : nvueLeave()
|
|
139
138
|
// #endif
|
|
140
139
|
// #ifndef APP-NVUE
|
|
141
|
-
newVal ? vueEnter() : vueLeave()
|
|
140
|
+
newVal ? vueEnter() : vueLeave();
|
|
142
141
|
// #endif
|
|
143
142
|
},
|
|
144
143
|
{ immediate: true },
|
|
145
|
-
)
|
|
144
|
+
);
|
|
146
145
|
|
|
147
146
|
const mergeStyle = computed(() => {
|
|
148
147
|
return {
|
|
149
148
|
// #ifndef APP-NVUE
|
|
150
|
-
transitionDuration: `${duration
|
|
149
|
+
transitionDuration: `${props.duration}ms`,
|
|
151
150
|
// display: `${this.display ? '' : 'none'}`,
|
|
152
|
-
transitionTimingFunction: timingFunction
|
|
151
|
+
transitionTimingFunction: props.timingFunction,
|
|
153
152
|
// #endif
|
|
154
153
|
// 避免自定义样式影响到动画属性,所以写在viewStyle前面
|
|
155
|
-
...customStyle
|
|
154
|
+
...props.customStyle,
|
|
156
155
|
...viewStyle,
|
|
157
|
-
}
|
|
158
|
-
})
|
|
156
|
+
};
|
|
157
|
+
});
|
|
159
158
|
|
|
160
159
|
/**
|
|
161
160
|
* @description 组件被点击发出事件
|
|
162
161
|
* */
|
|
163
162
|
const clickHandler = () => {
|
|
164
|
-
emit(
|
|
165
|
-
}
|
|
163
|
+
emit("click");
|
|
164
|
+
};
|
|
166
165
|
|
|
167
166
|
const onTransitionEnd = () => {
|
|
168
167
|
// 如果已经是结束的状态,无需再处理
|
|
169
|
-
if (transitionEnded.value) return
|
|
170
|
-
transitionEnded.value = true
|
|
168
|
+
if (transitionEnded.value) return;
|
|
169
|
+
transitionEnded.value = true;
|
|
171
170
|
// 发出组件动画执行后的事件
|
|
172
|
-
|
|
173
|
-
if (!show
|
|
174
|
-
display.value = false
|
|
175
|
-
hasInit.value = false
|
|
171
|
+
status.value === "leave" ? emit("afterLeave") : emit("afterEnter");
|
|
172
|
+
if (!props.show && display.value) {
|
|
173
|
+
display.value = false;
|
|
174
|
+
hasInit.value = false;
|
|
176
175
|
}
|
|
177
|
-
}
|
|
176
|
+
};
|
|
178
177
|
</script>
|
|
179
178
|
|
|
180
179
|
<style lang="scss" scoped>
|
|
181
180
|
/* #ifndef APP-NVUE */
|
|
182
181
|
// vue版本动画相关的样式抽离在外部文件
|
|
183
|
-
@import
|
|
182
|
+
@import "./index.scss";
|
|
184
183
|
/* #endif */
|
|
185
|
-
|
|
186
|
-
.hy-transition {
|
|
187
|
-
}
|
|
188
184
|
</style>
|