hy-app 0.3.1 → 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-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 +19 -20
- 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 +52 -26
- 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 -259
- 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-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/composables/usePopover.ts +236 -221
- package/composables/useQueue.ts +53 -52
- package/package.json +2 -2
- package/store/index.ts +9 -1
- package/typing/index.ts +0 -1
- package/typing/modules/common.d.ts +0 -2
- package/web-types.json +1 -1
|
@@ -30,9 +30,16 @@
|
|
|
30
30
|
:displayMultipleItems="list.length > 0 ? displayMultipleItems : 0"
|
|
31
31
|
:easingFunction="easingFunction"
|
|
32
32
|
>
|
|
33
|
-
<swiper-item
|
|
33
|
+
<swiper-item
|
|
34
|
+
class="hy-swiper__wrapper__item"
|
|
35
|
+
v-for="(item, index) in list"
|
|
36
|
+
:key="index"
|
|
37
|
+
>
|
|
34
38
|
<slot :record="item" :index="index">
|
|
35
|
-
<view
|
|
39
|
+
<view
|
|
40
|
+
class="hy-swiper__wrapper__item__wrapper"
|
|
41
|
+
:style="[itemStyle(index)]"
|
|
42
|
+
>
|
|
36
43
|
<!-- 在nvue中,image图片的宽度默认为屏幕宽度,需要通过flex:1撑开,另外必须设置高度才能显示图片 -->
|
|
37
44
|
<image
|
|
38
45
|
class="hy-swiper__wrapper__item__wrapper__image"
|
|
@@ -86,31 +93,32 @@
|
|
|
86
93
|
|
|
87
94
|
<script lang="ts">
|
|
88
95
|
export default {
|
|
89
|
-
name:
|
|
96
|
+
name: "hy-swiper",
|
|
90
97
|
options: {
|
|
91
98
|
addGlobalClass: true,
|
|
92
99
|
virtualHost: true,
|
|
93
|
-
styleIsolation:
|
|
100
|
+
styleIsolation: "shared",
|
|
94
101
|
},
|
|
95
|
-
}
|
|
102
|
+
};
|
|
96
103
|
</script>
|
|
97
104
|
|
|
98
105
|
<script setup lang="ts">
|
|
99
|
-
import { computed, toRefs, ref, watch, getCurrentInstance } from
|
|
100
|
-
import type { CSSProperties, PropType } from
|
|
101
|
-
import { addUnit, isVideo } from
|
|
102
|
-
import { IconConfig } from
|
|
103
|
-
import type { ISwiperEmits, SwiperList, SwiperVo } from
|
|
106
|
+
import { computed, toRefs, ref, watch, getCurrentInstance } from "vue";
|
|
107
|
+
import type { CSSProperties, PropType } from "vue";
|
|
108
|
+
import { addUnit, isVideo } from "../../utils";
|
|
109
|
+
import { IconConfig } from "../../config";
|
|
110
|
+
import type { ISwiperEmits, SwiperList, SwiperVo } from "./typing";
|
|
104
111
|
|
|
105
112
|
// 组件
|
|
106
|
-
import HyIcon from
|
|
107
|
-
import HySwiperIndicator from
|
|
113
|
+
import HyIcon from "../hy-icon/hy-icon.vue";
|
|
114
|
+
import HySwiperIndicator from "./hy-swiper-indicator.vue";
|
|
115
|
+
import type { SwiperEasingFunction } from "@uni-helper/uni-types";
|
|
108
116
|
|
|
109
117
|
/**
|
|
110
118
|
* 一般用于导航轮播,广告展示等场景,可开箱即用
|
|
111
119
|
* @displayName hy-swiper
|
|
112
120
|
*/
|
|
113
|
-
defineOptions({})
|
|
121
|
+
defineOptions({});
|
|
114
122
|
|
|
115
123
|
// const props = withDefaults(defineProps<IProps>(), defaultProps);
|
|
116
124
|
const props = defineProps({
|
|
@@ -122,7 +130,7 @@ const props = defineProps({
|
|
|
122
130
|
/** list数组中指定对象的目标属性名 */
|
|
123
131
|
keyName: {
|
|
124
132
|
type: String,
|
|
125
|
-
default:
|
|
133
|
+
default: "url",
|
|
126
134
|
},
|
|
127
135
|
/** 是否显示面板指示器 */
|
|
128
136
|
indicator: {
|
|
@@ -132,19 +140,22 @@ const props = defineProps({
|
|
|
132
140
|
/** 指示器非激活颜色 */
|
|
133
141
|
indicatorActiveColor: {
|
|
134
142
|
type: String,
|
|
135
|
-
default:
|
|
143
|
+
default: "#FFFFFF",
|
|
136
144
|
},
|
|
137
145
|
/** 指示器的激活颜色 */
|
|
138
146
|
indicatorInactiveColor: {
|
|
139
147
|
type: String,
|
|
140
|
-
default:
|
|
148
|
+
default: "rgba(255, 255, 255, 0.35)",
|
|
141
149
|
},
|
|
142
150
|
/** 指示器样式,可通过bottom,left,right进行定位 */
|
|
143
151
|
indicatorStyle: Object as PropType<CSSProperties>,
|
|
144
|
-
/**
|
|
152
|
+
/**
|
|
153
|
+
* 指示器模式
|
|
154
|
+
* @values line,dot
|
|
155
|
+
* */
|
|
145
156
|
indicatorMode: {
|
|
146
|
-
type: String
|
|
147
|
-
default:
|
|
157
|
+
type: String as PropType<HyApp.SwiperIndicatorModeType>,
|
|
158
|
+
default: "line",
|
|
148
159
|
},
|
|
149
160
|
/** 是否自动切换 */
|
|
150
161
|
autoplay: {
|
|
@@ -193,15 +204,18 @@ const props = defineProps({
|
|
|
193
204
|
type: Number,
|
|
194
205
|
default: 1,
|
|
195
206
|
},
|
|
196
|
-
/**
|
|
207
|
+
/**
|
|
208
|
+
* 指定swiper切换缓动动画类型, 只对微信小程序有效
|
|
209
|
+
* @values default,linear,easeInCubic,easeOutCubic,easeInOutCubic
|
|
210
|
+
* */
|
|
197
211
|
easingFunction: {
|
|
198
|
-
type: String
|
|
199
|
-
default:
|
|
212
|
+
type: String as PropType<SwiperEasingFunction>,
|
|
213
|
+
default: "default",
|
|
200
214
|
},
|
|
201
215
|
/** 图片的裁剪模式 */
|
|
202
216
|
imgMode: {
|
|
203
217
|
type: String,
|
|
204
|
-
default:
|
|
218
|
+
default: "aspectFill",
|
|
205
219
|
},
|
|
206
220
|
/** 组件高度 */
|
|
207
221
|
height: {
|
|
@@ -211,7 +225,7 @@ const props = defineProps({
|
|
|
211
225
|
/** 背景颜色 */
|
|
212
226
|
bgColor: {
|
|
213
227
|
type: String,
|
|
214
|
-
default:
|
|
228
|
+
default: "#f3f4f6",
|
|
215
229
|
},
|
|
216
230
|
/** 组件圆角,数值或带单位的字符串 */
|
|
217
231
|
radius: {
|
|
@@ -228,111 +242,111 @@ const props = defineProps({
|
|
|
228
242
|
type: Boolean,
|
|
229
243
|
default: false,
|
|
230
244
|
},
|
|
231
|
-
})
|
|
232
|
-
const
|
|
233
|
-
const emit = defineEmits<ISwiperEmits>()
|
|
245
|
+
});
|
|
246
|
+
const emit = defineEmits<ISwiperEmits>();
|
|
234
247
|
|
|
235
|
-
const instance = getCurrentInstance()
|
|
236
|
-
const currentIndex = ref<string | number>(0)
|
|
248
|
+
const instance = getCurrentInstance();
|
|
249
|
+
const currentIndex = ref<string | number>(0);
|
|
237
250
|
|
|
238
251
|
watch(
|
|
239
|
-
() => current
|
|
252
|
+
() => props.current,
|
|
240
253
|
(newVal) => {
|
|
241
|
-
currentIndex.value = newVal
|
|
254
|
+
currentIndex.value = newVal;
|
|
242
255
|
},
|
|
243
|
-
)
|
|
256
|
+
);
|
|
244
257
|
|
|
245
258
|
const hasTitle = computed(() => {
|
|
246
259
|
return (item: string | Record<string, any>) => {
|
|
247
|
-
if (typeof item ===
|
|
248
|
-
return item.title ??
|
|
260
|
+
if (typeof item === "object") {
|
|
261
|
+
return item.title ?? "";
|
|
249
262
|
} else {
|
|
250
|
-
return
|
|
263
|
+
return "";
|
|
251
264
|
}
|
|
252
|
-
}
|
|
253
|
-
})
|
|
265
|
+
};
|
|
266
|
+
});
|
|
254
267
|
|
|
255
268
|
/**
|
|
256
269
|
* @description 轮播图3D效果
|
|
257
270
|
* */
|
|
258
271
|
const itemStyle = computed(() => {
|
|
259
272
|
return (index: number): CSSProperties => {
|
|
260
|
-
const style: CSSProperties = {}
|
|
273
|
+
const style: CSSProperties = {};
|
|
261
274
|
// #ifndef APP-NVUE || MP-TOUTIAO
|
|
262
275
|
// 左右流出空间的写法不支持nvue和头条
|
|
263
276
|
// 只有配置了此二值,才加上对应的圆角,以及缩放
|
|
264
|
-
if (nextMargin
|
|
265
|
-
style.borderRadius = addUnit(radius
|
|
266
|
-
if (index !== currentIndex.value) style.transform =
|
|
277
|
+
if (props.nextMargin && props.previousMargin) {
|
|
278
|
+
style.borderRadius = addUnit(props.radius);
|
|
279
|
+
if (index !== currentIndex.value) style.transform = "scale(0.92)";
|
|
267
280
|
}
|
|
268
281
|
// #endif
|
|
269
|
-
return style
|
|
270
|
-
}
|
|
271
|
-
})
|
|
282
|
+
return style;
|
|
283
|
+
};
|
|
284
|
+
});
|
|
272
285
|
|
|
273
286
|
/**
|
|
274
287
|
* @description 获取目标路径,可能数组中为字符串,对象的形式,额外可指定对象的目标属性名keyName
|
|
275
288
|
* */
|
|
276
289
|
const getSource = (item: string | Record<string, any>): string => {
|
|
277
|
-
if (typeof item ===
|
|
278
|
-
if (typeof item ===
|
|
279
|
-
return
|
|
280
|
-
}
|
|
290
|
+
if (typeof item === "string") return item;
|
|
291
|
+
if (typeof item === "object" && props.keyName) return item[props.keyName];
|
|
292
|
+
return "";
|
|
293
|
+
};
|
|
281
294
|
|
|
282
295
|
/**
|
|
283
296
|
* @description 轮播切换事件
|
|
284
297
|
*/
|
|
285
298
|
const change = (e: SwiperVo) => {
|
|
286
299
|
// 当前的激活索引
|
|
287
|
-
const { current } = e.detail
|
|
288
|
-
pauseVideo(currentIndex.value)
|
|
289
|
-
currentIndex.value = current
|
|
290
|
-
emit(
|
|
291
|
-
emit(
|
|
292
|
-
}
|
|
300
|
+
const { current } = e.detail;
|
|
301
|
+
pauseVideo(currentIndex.value);
|
|
302
|
+
currentIndex.value = current;
|
|
303
|
+
emit("update:current", currentIndex.value);
|
|
304
|
+
emit("change", e.detail);
|
|
305
|
+
};
|
|
293
306
|
|
|
294
307
|
/**
|
|
295
308
|
* @description 切换轮播时,暂停视频播放
|
|
296
309
|
* */
|
|
297
310
|
const pauseVideo = (index: number | string) => {
|
|
298
|
-
const lastItem = getSource(list
|
|
311
|
+
const lastItem = getSource(props.list[Number(index)]);
|
|
299
312
|
if (isVideo(lastItem)) {
|
|
300
313
|
// 当视频隐藏时,暂停播放
|
|
301
|
-
const video = uni.createVideoContext(`video-${index}`, instance)
|
|
302
|
-
video.pause()
|
|
314
|
+
const video = uni.createVideoContext(`video-${index}`, instance);
|
|
315
|
+
video.pause();
|
|
303
316
|
}
|
|
304
|
-
}
|
|
317
|
+
};
|
|
305
318
|
|
|
306
319
|
/**
|
|
307
320
|
* @description 当一个轮播item为视频时,获取它的视频海报
|
|
308
321
|
* */
|
|
309
322
|
const getPoster = (item: string | SwiperList): string => {
|
|
310
|
-
return typeof item ===
|
|
311
|
-
}
|
|
323
|
+
return typeof item === "object" && item.poster ? item.poster : "";
|
|
324
|
+
};
|
|
312
325
|
|
|
313
326
|
/**
|
|
314
327
|
* @description 点击某个item
|
|
315
328
|
* */
|
|
316
329
|
const clickHandler = (index: number) => {
|
|
317
|
-
emit(
|
|
318
|
-
}
|
|
330
|
+
emit("click", index);
|
|
331
|
+
};
|
|
319
332
|
|
|
320
333
|
/**
|
|
321
334
|
* @description 判断链接是视频还是图片
|
|
322
335
|
* */
|
|
323
336
|
const getItemType = computed(() => {
|
|
324
337
|
return (item: string | Record<string, unknown>) => {
|
|
325
|
-
if (typeof item ===
|
|
326
|
-
if (typeof item ===
|
|
327
|
-
if (!item.type)
|
|
328
|
-
|
|
329
|
-
if (item.type ===
|
|
330
|
-
return
|
|
338
|
+
if (typeof item === "string") return isVideo(item) ? "video" : "image";
|
|
339
|
+
if (typeof item === "object" && props.keyName) {
|
|
340
|
+
if (!item.type)
|
|
341
|
+
return isVideo(item[props.keyName] as string) ? "video" : "image";
|
|
342
|
+
if (item.type === "image") return "image";
|
|
343
|
+
if (item.type === "video") return "video";
|
|
344
|
+
return "image";
|
|
331
345
|
}
|
|
332
|
-
}
|
|
333
|
-
})
|
|
346
|
+
};
|
|
347
|
+
});
|
|
334
348
|
</script>
|
|
335
349
|
|
|
336
350
|
<style lang="scss" scoped>
|
|
337
|
-
@import
|
|
351
|
+
@import "./index.scss";
|
|
338
352
|
</style>
|
|
@@ -15,7 +15,11 @@
|
|
|
15
15
|
:style="[nodeStyle]"
|
|
16
16
|
ref="hy-switch__node"
|
|
17
17
|
>
|
|
18
|
-
<hy-loading
|
|
18
|
+
<hy-loading
|
|
19
|
+
:show="loading"
|
|
20
|
+
:size="switchSize * 0.6"
|
|
21
|
+
mode="circle"
|
|
22
|
+
></hy-loading>
|
|
19
23
|
<view class="" v-if="!loading">
|
|
20
24
|
<slot>
|
|
21
25
|
<HyIcon
|
|
@@ -40,37 +44,36 @@
|
|
|
40
44
|
|
|
41
45
|
<script lang="ts">
|
|
42
46
|
export default {
|
|
43
|
-
name:
|
|
47
|
+
name: "hy-switch",
|
|
44
48
|
options: {
|
|
45
49
|
addGlobalClass: true,
|
|
46
50
|
virtualHost: true,
|
|
47
|
-
styleIsolation:
|
|
51
|
+
styleIsolation: "shared",
|
|
48
52
|
},
|
|
49
|
-
}
|
|
53
|
+
};
|
|
50
54
|
</script>
|
|
51
55
|
|
|
52
56
|
<script setup lang="ts">
|
|
53
|
-
import { toRefs, watch, nextTick, computed } from
|
|
54
|
-
import type { CSSProperties, PropType } from
|
|
55
|
-
import { addUnit, error } from
|
|
56
|
-
import type { ISwitchEmits } from
|
|
57
|
-
|
|
57
|
+
import { toRefs, watch, nextTick, computed } from "vue";
|
|
58
|
+
import type { CSSProperties, PropType } from "vue";
|
|
59
|
+
import { addUnit, error, isNumber } from "../../utils";
|
|
60
|
+
import type { ISwitchEmits, SwiperValue } from "./typing";
|
|
58
61
|
// 组件
|
|
59
|
-
import HyLoading from
|
|
60
|
-
import HyIcon from
|
|
61
|
-
import HyIconProps from
|
|
62
|
+
import HyLoading from "../hy-loading/hy-loading.vue";
|
|
63
|
+
import HyIcon from "../hy-icon/hy-icon.vue";
|
|
64
|
+
import type HyIconProps from "../hy-icon/typing";
|
|
62
65
|
|
|
63
66
|
/**
|
|
64
67
|
* 选择开关用于在打开和关闭状态之间进行切换。
|
|
65
68
|
* @displayName hy-switch
|
|
66
69
|
*/
|
|
67
|
-
defineOptions({})
|
|
70
|
+
defineOptions({});
|
|
68
71
|
|
|
69
72
|
// const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
70
73
|
const props = defineProps({
|
|
71
74
|
/** 通过v-model双向绑定的值 */
|
|
72
75
|
modelValue: {
|
|
73
|
-
type: [String, Number, Boolean]
|
|
76
|
+
type: [String, Number, Boolean] as PropType<SwiperValue>,
|
|
74
77
|
default: false,
|
|
75
78
|
},
|
|
76
79
|
/** 是否处于加载中 */
|
|
@@ -85,8 +88,8 @@ const props = defineProps({
|
|
|
85
88
|
},
|
|
86
89
|
/** 开关尺寸,单位px */
|
|
87
90
|
size: {
|
|
88
|
-
type: String,
|
|
89
|
-
default:
|
|
91
|
+
type: [String, Number] as PropType<string | number>,
|
|
92
|
+
default: "medium",
|
|
90
93
|
},
|
|
91
94
|
/** 打开时的背景色 */
|
|
92
95
|
activeColor: String,
|
|
@@ -94,12 +97,12 @@ const props = defineProps({
|
|
|
94
97
|
inactiveColor: String,
|
|
95
98
|
/** 打开选择器时通过change事件发出的值 */
|
|
96
99
|
activeValue: {
|
|
97
|
-
type: [String, Number, Boolean]
|
|
100
|
+
type: [String, Number, Boolean] as PropType<SwiperValue>,
|
|
98
101
|
default: true,
|
|
99
102
|
},
|
|
100
103
|
/** 关闭选择器时通过change事件发出的值 */
|
|
101
104
|
inactiveValue: {
|
|
102
|
-
type: [String, Number, Boolean]
|
|
105
|
+
type: [String, Number, Boolean] as PropType<SwiperValue>,
|
|
103
106
|
default: false,
|
|
104
107
|
},
|
|
105
108
|
/** 打开选择器时图标 */
|
|
@@ -122,37 +125,25 @@ const props = defineProps({
|
|
|
122
125
|
customStyle: Object as PropType<CSSProperties>,
|
|
123
126
|
/** 自定义外部类名 */
|
|
124
127
|
customClass: String,
|
|
125
|
-
})
|
|
126
|
-
const
|
|
127
|
-
modelValue,
|
|
128
|
-
size,
|
|
129
|
-
space,
|
|
130
|
-
inactiveValue,
|
|
131
|
-
activeValue,
|
|
132
|
-
activeColor,
|
|
133
|
-
disabled,
|
|
134
|
-
loading,
|
|
135
|
-
asyncChange,
|
|
136
|
-
inactiveColor,
|
|
137
|
-
} = toRefs(props)
|
|
138
|
-
const emit = defineEmits<ISwitchEmits>()
|
|
128
|
+
});
|
|
129
|
+
const emit = defineEmits<ISwitchEmits>();
|
|
139
130
|
|
|
140
131
|
watch(
|
|
141
|
-
() => modelValue
|
|
132
|
+
() => props.modelValue,
|
|
142
133
|
(newValue) => {
|
|
143
|
-
if (newValue !== inactiveValue
|
|
144
|
-
error(
|
|
134
|
+
if (newValue !== props.inactiveValue && newValue !== props.activeValue) {
|
|
135
|
+
error("v-model绑定的值必须为inactiveValue、activeValue二者之一");
|
|
145
136
|
}
|
|
146
137
|
},
|
|
147
138
|
{ immediate: true },
|
|
148
|
-
)
|
|
139
|
+
);
|
|
149
140
|
|
|
150
141
|
/**
|
|
151
142
|
* @description 是否打开
|
|
152
143
|
* */
|
|
153
144
|
const isActive = computed(() => {
|
|
154
|
-
return modelValue
|
|
155
|
-
})
|
|
145
|
+
return props.modelValue === props.activeValue;
|
|
146
|
+
});
|
|
156
147
|
|
|
157
148
|
/**
|
|
158
149
|
* @description 设置开关大小
|
|
@@ -162,81 +153,85 @@ const switchSize = computed((): number => {
|
|
|
162
153
|
small: 20,
|
|
163
154
|
medium: 25,
|
|
164
155
|
large: 30,
|
|
165
|
-
}
|
|
156
|
+
};
|
|
166
157
|
|
|
167
|
-
return
|
|
168
|
-
})
|
|
158
|
+
return isNumber(props.size) ? props.size : sz[props.size];
|
|
159
|
+
});
|
|
169
160
|
|
|
170
161
|
/**
|
|
171
162
|
* @description 开关样式
|
|
172
163
|
* */
|
|
173
164
|
const switchStyle = computed<CSSProperties>(() => {
|
|
174
|
-
let style: CSSProperties = {}
|
|
165
|
+
let style: CSSProperties = {};
|
|
175
166
|
// 这里需要加2,是为了腾出边框的距离,否则圆点node会和外边框紧贴在一起
|
|
176
|
-
style.width = addUnit(switchSize.value * 2 + 2)
|
|
177
|
-
style.height = addUnit(switchSize.value + 2)
|
|
167
|
+
style.width = addUnit(switchSize.value * 2 + 2);
|
|
168
|
+
style.height = addUnit(switchSize.value + 2);
|
|
178
169
|
// style.borderColor = this.value ? 'rgba(0, 0, 0, 0)' : 'rgba(0, 0, 0, 0.12)'
|
|
179
170
|
// 如果自定义了“非激活”演示,name边框颜色设置为透明(跟非激活颜色一致)
|
|
180
171
|
// 这里不能简单的设置为非激活的颜色,否则打开状态时,会有边框,所以需要透明
|
|
181
172
|
if (customInactiveColor.value) {
|
|
182
|
-
style.borderColor =
|
|
173
|
+
style.borderColor = "rgba(0, 0, 0, 0)";
|
|
183
174
|
}
|
|
184
|
-
style.backgroundColor = isActive.value
|
|
185
|
-
|
|
186
|
-
|
|
175
|
+
style.backgroundColor = isActive.value
|
|
176
|
+
? props.activeColor
|
|
177
|
+
: props.inactiveColor;
|
|
178
|
+
return style;
|
|
179
|
+
});
|
|
187
180
|
|
|
188
181
|
/**
|
|
189
182
|
* @description 圆圈样式
|
|
190
183
|
* */
|
|
191
184
|
const nodeStyle = computed<CSSProperties>(() => {
|
|
192
|
-
let style: CSSProperties = {}
|
|
185
|
+
let style: CSSProperties = {};
|
|
193
186
|
// 如果自定义非激活颜色,将node圆点的尺寸减少两个像素,让其与外边框距离更大一点
|
|
194
|
-
style.width = addUnit(switchSize.value - space
|
|
195
|
-
style.height = addUnit(switchSize.value - space
|
|
196
|
-
const translateX = isActive.value
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
})
|
|
187
|
+
style.width = addUnit(switchSize.value - props.space);
|
|
188
|
+
style.height = addUnit(switchSize.value - props.space);
|
|
189
|
+
const translateX = isActive.value
|
|
190
|
+
? addUnit(props.space)
|
|
191
|
+
: addUnit(switchSize.value);
|
|
192
|
+
style.transform = `translateX(-${translateX})`;
|
|
193
|
+
return style;
|
|
194
|
+
});
|
|
200
195
|
|
|
201
196
|
/**
|
|
202
197
|
* @description 背景样式
|
|
203
198
|
* */
|
|
204
199
|
const bgStyle = computed<CSSProperties>(() => {
|
|
205
|
-
let style: CSSProperties = {}
|
|
200
|
+
let style: CSSProperties = {};
|
|
206
201
|
// 这里配置一个多余的元素在HTML中,是为了让switch切换时,有更良好的背景色扩充体验(见实际效果)
|
|
207
|
-
style.width = addUnit(switchSize.value * 2 - switchSize.value / 2)
|
|
208
|
-
style.height = addUnit(switchSize.value)
|
|
209
|
-
style.backgroundColor = inactiveColor
|
|
202
|
+
style.width = addUnit(switchSize.value * 2 - switchSize.value / 2);
|
|
203
|
+
style.height = addUnit(switchSize.value);
|
|
204
|
+
style.backgroundColor = props.inactiveColor;
|
|
210
205
|
// 打开时,让此元素收缩,否则反之
|
|
211
|
-
style.transform = `scale(${isActive.value ? 0 : 1})
|
|
212
|
-
return style
|
|
213
|
-
})
|
|
206
|
+
style.transform = `scale(${isActive.value ? 0 : 1})`;
|
|
207
|
+
return style;
|
|
208
|
+
});
|
|
214
209
|
|
|
215
210
|
/**
|
|
216
211
|
* @description 自定义颜色
|
|
217
212
|
* */
|
|
218
213
|
const customInactiveColor = computed(() => {
|
|
219
214
|
// 之所以需要判断是否自定义了“非激活”颜色,是为了让node圆点离外边框更宽一点的距离
|
|
220
|
-
return inactiveColor
|
|
221
|
-
})
|
|
215
|
+
return props.inactiveColor !== "#fff" && props.inactiveColor !== "#ffffff";
|
|
216
|
+
});
|
|
222
217
|
|
|
223
218
|
/**
|
|
224
219
|
* @description 点击事件
|
|
225
220
|
* */
|
|
226
221
|
const clickHandler = () => {
|
|
227
|
-
if (!disabled
|
|
228
|
-
const oldValue = isActive.value ? inactiveValue
|
|
229
|
-
if (!asyncChange
|
|
230
|
-
emit(
|
|
222
|
+
if (!props.disabled && !props.loading) {
|
|
223
|
+
const oldValue = isActive.value ? props.inactiveValue : props.activeValue;
|
|
224
|
+
if (!props.asyncChange) {
|
|
225
|
+
emit("update:modelValue", oldValue);
|
|
231
226
|
}
|
|
232
227
|
// 放到下一个生命周期,因为双向绑定的value修改父组件状态需要时间,且是异步的
|
|
233
228
|
nextTick(() => {
|
|
234
|
-
emit(
|
|
235
|
-
})
|
|
229
|
+
emit("change", oldValue);
|
|
230
|
+
});
|
|
236
231
|
}
|
|
237
|
-
}
|
|
232
|
+
};
|
|
238
233
|
</script>
|
|
239
234
|
|
|
240
235
|
<style lang="scss" scoped>
|
|
241
|
-
@import
|
|
236
|
+
@import "./index.scss";
|
|
242
237
|
</style>
|
|
@@ -1,69 +1,71 @@
|
|
|
1
|
-
import type { CSSProperties } from
|
|
2
|
-
import { HyApp } from
|
|
3
|
-
import type IconProps from
|
|
1
|
+
import type { CSSProperties } from "vue";
|
|
2
|
+
import { HyApp } from "@/package/typing/modules/common";
|
|
3
|
+
import type IconProps from "../hy-icon/typing";
|
|
4
4
|
|
|
5
5
|
export default interface HySwitchProps {
|
|
6
6
|
/**
|
|
7
7
|
* @description 通过v-model双向绑定的值 (默认 false )
|
|
8
8
|
* */
|
|
9
|
-
modelValue: boolean | string | number
|
|
9
|
+
modelValue: boolean | string | number;
|
|
10
10
|
/**
|
|
11
11
|
* @description 是否处于加载中(默认 false )
|
|
12
12
|
* */
|
|
13
|
-
loading?: boolean
|
|
13
|
+
loading?: boolean;
|
|
14
14
|
/**
|
|
15
15
|
* @description 是否禁用(默认 false )
|
|
16
16
|
* */
|
|
17
|
-
disabled?: boolean
|
|
17
|
+
disabled?: boolean;
|
|
18
18
|
/**
|
|
19
19
|
* @description 开关尺寸,单位px (默认 25 )
|
|
20
20
|
* */
|
|
21
|
-
size?: HyApp.SizeType | string | number
|
|
21
|
+
size?: HyApp.SizeType | string | number;
|
|
22
22
|
/**
|
|
23
23
|
* @description 打开时的背景色 (默认 '#2979ff' )
|
|
24
24
|
* */
|
|
25
|
-
activeColor?: string
|
|
25
|
+
activeColor?: string;
|
|
26
26
|
/**
|
|
27
27
|
* @description 关闭时的背景色 (默认 '#ffffff' )
|
|
28
28
|
* */
|
|
29
|
-
inactiveColor?: string
|
|
29
|
+
inactiveColor?: string;
|
|
30
30
|
/**
|
|
31
31
|
* @description 打开选择器时通过change事件发出的值 (默认 true )
|
|
32
32
|
* */
|
|
33
|
-
activeValue?: boolean | string | number
|
|
33
|
+
activeValue?: boolean | string | number;
|
|
34
34
|
/**
|
|
35
35
|
* @description 关闭选择器时通过change事件发出的值 (默认 false )
|
|
36
36
|
* */
|
|
37
|
-
inactiveValue?: boolean | string | number
|
|
37
|
+
inactiveValue?: boolean | string | number;
|
|
38
38
|
/**
|
|
39
39
|
* @description 打开选择器时图标
|
|
40
40
|
* */
|
|
41
|
-
activeIcon?: string
|
|
41
|
+
activeIcon?: string;
|
|
42
42
|
/**
|
|
43
43
|
* @description 关闭选择器时图标
|
|
44
44
|
* */
|
|
45
|
-
inactiveIcon?: string
|
|
45
|
+
inactiveIcon?: string;
|
|
46
46
|
/**
|
|
47
47
|
* @description 图标
|
|
48
48
|
* */
|
|
49
|
-
icon?: IconProps
|
|
49
|
+
icon?: IconProps;
|
|
50
50
|
/**
|
|
51
51
|
* @description 是否开启异步变更,开启后需要手动控制输入值 (默认 false )
|
|
52
52
|
* */
|
|
53
|
-
asyncChange?: boolean
|
|
53
|
+
asyncChange?: boolean;
|
|
54
54
|
/**
|
|
55
55
|
* @description 圆点与外边框的距离 (默认 0 )
|
|
56
56
|
* */
|
|
57
|
-
space?: number
|
|
57
|
+
space?: number;
|
|
58
58
|
/**
|
|
59
59
|
* @description 定义需要用到的外部样式
|
|
60
60
|
* */
|
|
61
|
-
customStyle?: CSSProperties
|
|
61
|
+
customStyle?: CSSProperties;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
export type SwiperValue = boolean | number | string;
|
|
65
|
+
|
|
64
66
|
export interface ISwitchEmits {
|
|
65
67
|
/** 改变值触发 */
|
|
66
|
-
(e:
|
|
68
|
+
(e: "change", value: SwiperValue): void;
|
|
67
69
|
/** 改变值触发 */
|
|
68
|
-
(e:
|
|
70
|
+
(e: "update:modelValue", value: SwiperValue): void;
|
|
69
71
|
}
|