@ecolovo/uniapp-components 2.0.2 → 2.0.4
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/components/aspect/aspect.vue +4 -2
- package/components/badge/badge.scss +3 -1
- package/components/badge/badge.vue +15 -11
- package/components/button/button.vue +69 -22
- package/components/checkbox/checkbox.scss +1 -1
- package/components/checkbox/checkbox.vue +54 -23
- package/components/checkbox-group/checkbox-group.vue +11 -4
- package/components/checkbox-group2/checkbox-group2.vue +23 -8
- package/components/checkbox-group2/checkbox2.vue +11 -4
- package/components/data-list/data-list.vue +25 -5
- package/components/date-picker/date-picker-view.vue +45 -16
- package/components/date-picker/date-picker.vue +58 -18
- package/components/dialog/dialog-content.vue +39 -12
- package/components/dialog/dialog.vue +30 -19
- package/components/dropdown/dropdown.vue +29 -6
- package/components/empty/empty.vue +10 -3
- package/components/flex/flex.vue +16 -6
- package/components/form-item/form-item.vue +13 -4
- package/components/icon/icon.scss +9 -0
- package/components/icon/icon.vue +46 -8
- package/components/image/image.vue +13 -8
- package/components/index.d.ts +50 -0
- package/components/index.js +50 -0
- package/components/index.ts +50 -0
- package/components/input/input.vue +13 -3
- package/components/input/password-input.vue +2 -2
- package/components/list-page/list-page.vue +24 -6
- package/components/load-more/load-more.vue +7 -2
- package/components/loading/animations/loading-animation3.vue +10 -5
- package/components/loading/animations/loading-animation4.vue +65 -8
- package/components/loading/loading.vue +7 -6
- package/components/message-box/message-box.d.ts +18 -0
- package/components/message-box/message-box.js +1 -0
- package/components/message-box/message-box.ts +18 -0
- package/components/message-box/message-box.vue +53 -21
- package/components/number-dialog/number-dialog.vue +61 -21
- package/components/number-input/number-input.vue +53 -18
- package/components/numpad/numpad.vue +11 -5
- package/components/page/page-body.scss +1 -1
- package/components/page/page-body.vue +79 -11
- package/components/page/page-footer.vue +11 -5
- package/components/page/page-header.vue +49 -24
- package/components/page/page.scss +2 -1
- package/components/page/page.vue +74 -29
- package/components/picker/picker-popup.vue +96 -68
- package/components/picker/picker.vue +11 -5
- package/components/popover/popover-content.vue +59 -19
- package/components/popover/popover-mask.vue +18 -11
- package/components/popover/popover.vue +13 -3
- package/components/popup/popup-content.vue +35 -11
- package/components/popup/popup.vue +36 -17
- package/components/price/price.scss +1 -0
- package/components/price/price.vue +18 -7
- package/components/search/search.vue +24 -10
- package/components/searching/searching.scss +14 -0
- package/components/searching/searching.vue +17 -10
- package/components/selector/selector.vue +10 -3
- package/components/switch/switch.vue +31 -10
- package/components/tab/tab.vue +41 -8
- package/components/textarea/textarea.vue +55 -13
- package/composable/component-name.js +2 -1
- package/composable/component-name.ts +2 -1
- package/composable/message-box.d.ts +35 -0
- package/composable/message-box.js +56 -0
- package/composable/message-box.ts +98 -0
- package/configs/index.d.ts +8 -1
- package/configs/index.js +14 -3
- package/configs/index.ts +8 -1
- package/easyCom.js +10 -5
- package/easyCom.ts +10 -5
- package/globals.d.ts +36 -0
- package/index.d.ts +4 -0
- package/index.js +4 -0
- package/index.ts +5 -0
- package/package.json +14 -6
- package/styles/global.scss +123 -2
- package/styles/reset.scss +5 -0
- package/styles/utils/css-var.scss +11 -11
- package/styles/utils/index.scss +0 -1
- package/styles/var/component.scss +23 -20
- package/styles/var/theme.scss +3 -3
- package/utils/date.d.ts +7 -2
- package/utils/date.js +31 -10
- package/utils/date.ts +20 -6
- package/utils/price.d.ts +4 -1
- package/utils/price.js +12 -7
- package/utils/price.ts +8 -3
- package/utils/round.js +4 -1
- package/utils/round.ts +4 -1
- package/utils/windowInfo.d.ts +0 -1
- package/styles/utils/z-index.scss +0 -10
|
@@ -22,7 +22,7 @@ defineOptions({
|
|
|
22
22
|
const classNames = useClassNames('aspect');
|
|
23
23
|
|
|
24
24
|
type _Props = {
|
|
25
|
-
/**
|
|
25
|
+
/** 高与宽的比例,默认为 1,即宽高相等,2 表示高为宽的 2 倍 */
|
|
26
26
|
ratio?: string | number;
|
|
27
27
|
};
|
|
28
28
|
|
|
@@ -34,7 +34,9 @@ defineEmits<{
|
|
|
34
34
|
(event: 'click'): void;
|
|
35
35
|
}>();
|
|
36
36
|
|
|
37
|
-
const inlineStyle = computed(
|
|
37
|
+
const inlineStyle = computed(
|
|
38
|
+
() => `padding-top: ${100 * Number(props.ratio)}%;`
|
|
39
|
+
);
|
|
38
40
|
</script>
|
|
39
41
|
|
|
40
42
|
<style lang="css" module>
|
|
@@ -40,13 +40,18 @@ const props = withDefaults(defineProps<_Props>(), {
|
|
|
40
40
|
max: 99,
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
-
defineEmits<{
|
|
44
|
-
(event: 'click'): void;
|
|
45
|
-
}>();
|
|
46
|
-
|
|
47
43
|
const showValue = computed(() => {
|
|
44
|
+
if (!props.value) return '';
|
|
45
|
+
|
|
48
46
|
const numberValue = Number(props.value);
|
|
49
|
-
|
|
47
|
+
// 如果传入的值不可转为数字,则原样显示
|
|
48
|
+
if (Number.isNaN(numberValue)) return props.value;
|
|
49
|
+
|
|
50
|
+
return numberValue && numberValue > 0
|
|
51
|
+
? numberValue > props.max
|
|
52
|
+
? `${props.max}+`
|
|
53
|
+
: numberValue
|
|
54
|
+
: '';
|
|
50
55
|
});
|
|
51
56
|
</script>
|
|
52
57
|
|
|
@@ -56,7 +61,7 @@ const showValue = computed(() => {
|
|
|
56
61
|
|
|
57
62
|
// 定义外部变量
|
|
58
63
|
%external-vars {
|
|
59
|
-
@include UTILS__DEFINE_COMPONENT_VARS(
|
|
64
|
+
@include UTILS__DEFINE_COMPONENT_VARS('badge', $badge);
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
$__translate: UTILS__LOCAL_VAR(translate);
|
|
@@ -65,6 +70,7 @@ $__height: UTILS__LOCAL_VAR(height);
|
|
|
65
70
|
$__border: UTILS__LOCAL_VAR(border);
|
|
66
71
|
$__color: UTILS__LOCAL_VAR(color);
|
|
67
72
|
$__background: UTILS__LOCAL_VAR(background);
|
|
73
|
+
$__padding-x: UTILS__LOCAL_VAR(padding-x);
|
|
68
74
|
|
|
69
75
|
.Badge {
|
|
70
76
|
@extend %external-vars;
|
|
@@ -74,16 +80,14 @@ $__background: UTILS__LOCAL_VAR(background);
|
|
|
74
80
|
width: fit-content;
|
|
75
81
|
|
|
76
82
|
.Badge--box {
|
|
77
|
-
|
|
78
|
-
|
|
83
|
+
box-sizing: border-box;
|
|
79
84
|
position: absolute;
|
|
80
85
|
top: 0;
|
|
81
86
|
right: 0;
|
|
82
87
|
z-index: 1;
|
|
83
|
-
padding: 0
|
|
84
|
-
box-sizing: content-box;
|
|
88
|
+
padding: 0 $__padding-x;
|
|
85
89
|
text-align: center;
|
|
86
|
-
min-width:
|
|
90
|
+
min-width: $__height;
|
|
87
91
|
height: $__height;
|
|
88
92
|
line-height: $__height;
|
|
89
93
|
font-size: $__font-size;
|
|
@@ -34,7 +34,10 @@
|
|
|
34
34
|
@agreeprivacyauthorization="$emit('agreeprivacyauthorization', $event)"
|
|
35
35
|
>
|
|
36
36
|
<!-- 线性按钮边框:仅在线性按钮且不是禁用态时显示 -->
|
|
37
|
-
<view
|
|
37
|
+
<view
|
|
38
|
+
v-if="!disabled && !text && plain"
|
|
39
|
+
:class="$style['Button--plain-border']"
|
|
40
|
+
></view>
|
|
38
41
|
<!-- 仅在配置了图标或文本按钮处于加载态(不能处于禁用态)时显示 -->
|
|
39
42
|
<template v-if="text">
|
|
40
43
|
<icon-cpn
|
|
@@ -55,9 +58,15 @@
|
|
|
55
58
|
<slot></slot>
|
|
56
59
|
</view>
|
|
57
60
|
<!-- 点击态样式:仅在非文本按钮且不是禁用态时显示 -->
|
|
58
|
-
<view
|
|
61
|
+
<view
|
|
62
|
+
v-if="!disabled && !text"
|
|
63
|
+
:class="$style['Button--active-mask']"
|
|
64
|
+
></view>
|
|
59
65
|
<!-- 加载态样式:仅在非文本按钮处于加载态(不能处于禁用态)时显示 -->
|
|
60
|
-
<view
|
|
66
|
+
<view
|
|
67
|
+
v-if="!disabled && !text && isLoading"
|
|
68
|
+
:class="$style['Button--loading-icon']"
|
|
69
|
+
>
|
|
61
70
|
<icon-cpn icon="loading-dot-spinner" spinning />
|
|
62
71
|
</view>
|
|
63
72
|
</button>
|
|
@@ -68,6 +77,13 @@ import { computed, ref, useCssModule } from 'vue';
|
|
|
68
77
|
import useClassNames from '../../composable/component-name';
|
|
69
78
|
import IconCpn from '../icon/icon.vue';
|
|
70
79
|
|
|
80
|
+
/**
|
|
81
|
+
* **组件使用说明:**
|
|
82
|
+
*
|
|
83
|
+
* 当 async 为 false 时,组件会按传入的 coolDown 控制两次点击之间的间隔
|
|
84
|
+
* 当 async 为 true 时,需要在父组件监听 click 事件的回调函数中调用传入的 resolve 或 reject 方法,否则按钮将持续处于 loading 状态
|
|
85
|
+
*/
|
|
86
|
+
|
|
71
87
|
defineOptions({
|
|
72
88
|
options: {
|
|
73
89
|
styleIsolation: 'shared',
|
|
@@ -86,7 +102,12 @@ type _Props = {
|
|
|
86
102
|
/** 按钮主题 */
|
|
87
103
|
type?: string;
|
|
88
104
|
/** 对应小程序的 openType */
|
|
89
|
-
openType?:
|
|
105
|
+
openType?:
|
|
106
|
+
| 'contact'
|
|
107
|
+
| 'getPhoneNumber'
|
|
108
|
+
| 'getUserInfo'
|
|
109
|
+
| 'chooseAvatar'
|
|
110
|
+
| 'agreePrivacyAuthorization';
|
|
90
111
|
/** 按钮冷却时间,单位毫秒,两次点击之间的最小间隔,为 `0` 时可连续点击 */
|
|
91
112
|
coolDown?: number;
|
|
92
113
|
/** 是否异步事件 */
|
|
@@ -124,8 +145,8 @@ const props = withDefaults(defineProps<_Props>(), {
|
|
|
124
145
|
});
|
|
125
146
|
|
|
126
147
|
const emit = defineEmits<{
|
|
127
|
-
(event: 'click', payload?:
|
|
128
|
-
(event: 'getphonenumber', payload?:
|
|
148
|
+
(event: 'click', payload?: UniApp.PromiseResolvers<unknown>): void;
|
|
149
|
+
(event: 'getphonenumber', payload?: UniApp.GetPhoneNumberEvent): void;
|
|
129
150
|
(event: 'getuserinfo', payload?: unknown): void;
|
|
130
151
|
(event: 'error', payload?: unknown): void;
|
|
131
152
|
(event: 'opensetting', payload?: unknown): void;
|
|
@@ -140,19 +161,35 @@ const isCoolingDown = ref(false);
|
|
|
140
161
|
/** 按钮是否处于请求状态 */
|
|
141
162
|
const isAsyncLoading = ref(false);
|
|
142
163
|
|
|
143
|
-
/**
|
|
144
|
-
const inlineCssVar = computed(
|
|
164
|
+
/** 按钮主题样式 */
|
|
165
|
+
const inlineCssVar = computed(
|
|
166
|
+
() => `--theme-from-prop: var(--button-theme-${props.type});`
|
|
167
|
+
);
|
|
145
168
|
/** 按钮尺寸样式 */
|
|
146
169
|
const buttonSize = computed(() => {
|
|
147
170
|
if (props.text) {
|
|
148
|
-
return props.large
|
|
171
|
+
return props.large
|
|
172
|
+
? $style['Button--text-large']
|
|
173
|
+
: props.small
|
|
174
|
+
? $style['Button--text-small']
|
|
175
|
+
: '';
|
|
149
176
|
}
|
|
150
|
-
return props.large
|
|
177
|
+
return props.large
|
|
178
|
+
? $style['Button--block-large']
|
|
179
|
+
: props.small
|
|
180
|
+
? $style['Button--block-small']
|
|
181
|
+
: '';
|
|
151
182
|
});
|
|
152
|
-
/**
|
|
183
|
+
/** 按钮是否处于 loading 状态 */
|
|
153
184
|
const isLoading = computed(() => props.loading || isAsyncLoading.value);
|
|
154
|
-
/**
|
|
155
|
-
const isNotClickable = computed(
|
|
185
|
+
/** 按钮是否可被点击 */
|
|
186
|
+
const isNotClickable = computed(
|
|
187
|
+
() =>
|
|
188
|
+
props.disabled ||
|
|
189
|
+
props.forbidClick ||
|
|
190
|
+
isLoading.value ||
|
|
191
|
+
isCoolingDown.value
|
|
192
|
+
);
|
|
156
193
|
|
|
157
194
|
/** 进入冷却 */
|
|
158
195
|
const $_coolDown = () => {
|
|
@@ -164,8 +201,9 @@ const $_coolDown = () => {
|
|
|
164
201
|
}, props.coolDown);
|
|
165
202
|
}
|
|
166
203
|
};
|
|
204
|
+
|
|
167
205
|
/** 点击按钮响应 */
|
|
168
|
-
const onClick =
|
|
206
|
+
const onClick = () => {
|
|
169
207
|
if (isNotClickable.value) {
|
|
170
208
|
return;
|
|
171
209
|
}
|
|
@@ -178,7 +216,13 @@ const onClick = async () => {
|
|
|
178
216
|
}
|
|
179
217
|
|
|
180
218
|
isAsyncLoading.value = true;
|
|
181
|
-
const { promise, resolve, reject } = Promise.withResolvers();
|
|
219
|
+
// const { promise, resolve, reject } = Promise.withResolvers();
|
|
220
|
+
let resolve: UniApp.PromiseResolver<unknown>,
|
|
221
|
+
reject: UniApp.PromiseRejector<unknown>;
|
|
222
|
+
const promise = new Promise((res, rej) => {
|
|
223
|
+
resolve = res;
|
|
224
|
+
reject = rej;
|
|
225
|
+
});
|
|
182
226
|
promise.finally(() => {
|
|
183
227
|
isAsyncLoading.value = false;
|
|
184
228
|
});
|
|
@@ -197,7 +241,7 @@ const onClick = async () => {
|
|
|
197
241
|
|
|
198
242
|
// 定义外部变量
|
|
199
243
|
%external-vars {
|
|
200
|
-
@include UTILS__DEFINE_COMPONENT_VARS(
|
|
244
|
+
@include UTILS__DEFINE_COMPONENT_VARS('button', $button);
|
|
201
245
|
}
|
|
202
246
|
|
|
203
247
|
%button-themes {
|
|
@@ -259,7 +303,10 @@ $button-sizes: (
|
|
|
259
303
|
|
|
260
304
|
.Button--plain,
|
|
261
305
|
.Button-text {
|
|
262
|
-
--button-color: var(
|
|
306
|
+
--button-color: var(
|
|
307
|
+
#{UTILS__VAR_NAME('button', text-color)},
|
|
308
|
+
#{UTILS__LOCAL_VAR(theme)}
|
|
309
|
+
);
|
|
263
310
|
--button-background: transparent;
|
|
264
311
|
}
|
|
265
312
|
|
|
@@ -306,7 +353,7 @@ $button-sizes: (
|
|
|
306
353
|
}
|
|
307
354
|
}
|
|
308
355
|
|
|
309
|
-
.Button--loading {
|
|
356
|
+
.Button--loading-icon {
|
|
310
357
|
position: absolute;
|
|
311
358
|
top: 50%;
|
|
312
359
|
left: 50%;
|
|
@@ -316,8 +363,8 @@ $button-sizes: (
|
|
|
316
363
|
}
|
|
317
364
|
|
|
318
365
|
&.Button--disabled {
|
|
319
|
-
color: #fff;
|
|
320
|
-
background: #ccc;
|
|
366
|
+
--button-color: #fff;
|
|
367
|
+
--button-background: #ccc;
|
|
321
368
|
}
|
|
322
369
|
}
|
|
323
370
|
|
|
@@ -373,11 +420,11 @@ $button-sizes: (
|
|
|
373
420
|
|
|
374
421
|
&.Button--active,
|
|
375
422
|
&.Button--not-clickable {
|
|
376
|
-
color: #999;
|
|
423
|
+
--button-color: #999;
|
|
377
424
|
}
|
|
378
425
|
|
|
379
426
|
&.Button--disabled {
|
|
380
|
-
color: #ccc;
|
|
427
|
+
--button-color: #ccc;
|
|
381
428
|
}
|
|
382
429
|
}
|
|
383
430
|
</style>
|
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
v-if="hasIcon"
|
|
5
5
|
:icon="usingIcon || ''"
|
|
6
6
|
tap-size="50rpx"
|
|
7
|
-
:class="[
|
|
7
|
+
:class="[
|
|
8
|
+
$style['Checkbox--icon'],
|
|
9
|
+
{ [$style['Checkbox--checked']]: isChecked },
|
|
10
|
+
]"
|
|
8
11
|
/>
|
|
9
12
|
<view :class="$style['Checkbox--text']">
|
|
10
13
|
<slot>{{ label }}</slot>
|
|
@@ -13,7 +16,8 @@
|
|
|
13
16
|
</template>
|
|
14
17
|
|
|
15
18
|
<script lang="ts" setup>
|
|
16
|
-
import { computed,
|
|
19
|
+
import { computed, inject, ref } from 'vue';
|
|
20
|
+
import type { ComputedRef, Ref } from 'vue';
|
|
17
21
|
import IconCpn from '../icon/icon.vue';
|
|
18
22
|
import useClassNames from '../../composable/component-name';
|
|
19
23
|
|
|
@@ -25,23 +29,26 @@ defineOptions({
|
|
|
25
29
|
});
|
|
26
30
|
|
|
27
31
|
const classNames = useClassNames('checkbox');
|
|
32
|
+
|
|
28
33
|
/** 表单是否只读 */
|
|
29
34
|
const isFormReadonly = inject<ComputedRef<boolean>>(
|
|
30
35
|
'ecolovo/form/readonly',
|
|
31
36
|
computed(() => false)
|
|
32
37
|
);
|
|
33
38
|
/** 勾选框组当前选中值 */
|
|
34
|
-
const groupCheckedValue = inject<
|
|
35
|
-
|
|
36
|
-
);
|
|
39
|
+
const groupCheckedValue = inject<
|
|
40
|
+
Ref<undefined | string | number | boolean | Array<unknown>>
|
|
41
|
+
>('ecolovo/checkboxGroup/checkedValue', ref(undefined));
|
|
37
42
|
/** 勾选框组的 props */
|
|
38
|
-
const groupProps = inject<null | Pick<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
);
|
|
43
|
+
const groupProps = inject<null | Pick<
|
|
44
|
+
_Props,
|
|
45
|
+
'radio' | 'icon' | 'checkedIcon' | 'uncheckedIcon'
|
|
46
|
+
>>('ecolovo/checkboxGroup/props', null);
|
|
42
47
|
/** 勾选框组勾选选项方法 */
|
|
43
|
-
const groupCheck =
|
|
44
|
-
|
|
48
|
+
const groupCheck = inject<
|
|
49
|
+
| null
|
|
50
|
+
| ((val: undefined | string | number | boolean | Array<unknown>) => void)
|
|
51
|
+
>('ecolovo/checkboxGroup/check', null);
|
|
45
52
|
|
|
46
53
|
type _Props = {
|
|
47
54
|
/** 不在勾选框组中时使用,用于 v-model ,只能是 boolean 类型 */
|
|
@@ -80,33 +87,57 @@ const emit = defineEmits<{
|
|
|
80
87
|
|
|
81
88
|
const innerChecked = ref(false);
|
|
82
89
|
|
|
90
|
+
/** 是否只读 */
|
|
91
|
+
const isReadonly = computed<boolean>(() =>
|
|
92
|
+
props.readonly !== undefined ? props.readonly : isFormReadonly.value
|
|
93
|
+
);
|
|
83
94
|
/** 是否在 checkbox-group 中 */
|
|
84
95
|
const isInCheckboxGroup = computed<boolean>(() => !!groupProps);
|
|
85
|
-
/** 是否只读 */
|
|
86
|
-
const isReadonly = computed<boolean>(() => (props.readonly !== undefined ? props.readonly : isFormReadonly.value));
|
|
87
96
|
/** 是否显示勾选图标 */
|
|
88
|
-
const hasIcon = computed<boolean>(() =>
|
|
97
|
+
const hasIcon = computed<boolean>(() =>
|
|
98
|
+
props.icon !== undefined ? props.icon : groupProps?.icon ?? true
|
|
99
|
+
);
|
|
89
100
|
/** 是否为单选 */
|
|
90
|
-
const isRadio = computed<boolean>(() =>
|
|
101
|
+
const isRadio = computed<boolean>(() =>
|
|
102
|
+
props.radio !== undefined ? props.radio : groupProps?.radio || false
|
|
103
|
+
);
|
|
91
104
|
/** 最终使用的选中态的图标 */
|
|
92
105
|
const usingCheckedIcon = computed<string>(
|
|
93
|
-
() =>
|
|
106
|
+
() =>
|
|
107
|
+
props.checkedIcon ||
|
|
108
|
+
groupProps?.checkedIcon ||
|
|
109
|
+
(isRadio.value ? 'radio-checked' : 'checkbox-checked')
|
|
94
110
|
);
|
|
95
111
|
/** 最终使用的未选中态的图标 */
|
|
96
112
|
const usingUncheckedIcon = computed(
|
|
97
|
-
() =>
|
|
113
|
+
() =>
|
|
114
|
+
props.uncheckedIcon ||
|
|
115
|
+
groupProps?.uncheckedIcon ||
|
|
116
|
+
(isRadio.value ? 'radio-unchecked' : 'checkbox-unchecked')
|
|
98
117
|
);
|
|
99
118
|
/** 最终使用的图标 */
|
|
100
|
-
const usingIcon = computed(() =>
|
|
119
|
+
const usingIcon = computed(() =>
|
|
120
|
+
isChecked.value ? usingCheckedIcon.value : usingUncheckedIcon.value
|
|
121
|
+
);
|
|
101
122
|
/** 是否勾选 */
|
|
102
123
|
const isChecked = computed<boolean>({
|
|
103
124
|
get() {
|
|
104
125
|
if (isInCheckboxGroup.value) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
126
|
+
if (isRadio.value) return props.value === groupCheckedValue.value;
|
|
127
|
+
if (
|
|
128
|
+
groupCheckedValue.value !== undefined &&
|
|
129
|
+
groupCheckedValue.value !== null &&
|
|
130
|
+
!Array.isArray(groupCheckedValue.value)
|
|
131
|
+
) {
|
|
132
|
+
throw Error(
|
|
133
|
+
'CheckboxGroup 的值应为数组类型,或将其设为 radio 类型'
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
return groupCheckedValue.value?.includes(props.value) || false;
|
|
108
137
|
}
|
|
109
|
-
return props.modelValue === undefined
|
|
138
|
+
return props.modelValue === undefined
|
|
139
|
+
? innerChecked.value
|
|
140
|
+
: (props.modelValue as boolean);
|
|
110
141
|
},
|
|
111
142
|
set(val) {
|
|
112
143
|
emit('update:modelValue', val);
|
|
@@ -141,7 +172,7 @@ const toggle = (checked?: boolean) => {
|
|
|
141
172
|
|
|
142
173
|
// 定义外部变量
|
|
143
174
|
%external-vars {
|
|
144
|
-
@include UTILS__DEFINE_COMPONENT_VARS(
|
|
175
|
+
@include UTILS__DEFINE_COMPONENT_VARS('checkbox', $checkbox);
|
|
145
176
|
}
|
|
146
177
|
|
|
147
178
|
.Checkbox {
|
|
@@ -39,15 +39,22 @@ const props = withDefaults(defineProps<_Props>(), {
|
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
const emit = defineEmits<{
|
|
42
|
-
(
|
|
42
|
+
(
|
|
43
|
+
event: 'update:modelValue',
|
|
44
|
+
value?: string | number | boolean | Array<unknown>
|
|
45
|
+
): void;
|
|
43
46
|
(event: 'change', value?: string | number | boolean | Array<unknown>): void;
|
|
44
47
|
}>();
|
|
45
48
|
|
|
46
|
-
const checkedValue = ref<
|
|
49
|
+
const checkedValue = ref<
|
|
50
|
+
undefined | string | number | boolean | Array<unknown>
|
|
51
|
+
>(undefined);
|
|
47
52
|
|
|
48
53
|
const currentValue = computed({
|
|
49
54
|
get: function () {
|
|
50
|
-
return props.modelValue === undefined
|
|
55
|
+
return props.modelValue === undefined
|
|
56
|
+
? checkedValue.value
|
|
57
|
+
: props.modelValue;
|
|
51
58
|
},
|
|
52
59
|
set: function (val) {
|
|
53
60
|
if (checkedValue.value === val) return;
|
|
@@ -95,7 +102,7 @@ provide('ecolovo/checkboxGroup/check', check);
|
|
|
95
102
|
</script>
|
|
96
103
|
|
|
97
104
|
<style lang="scss" module>
|
|
98
|
-
@use '../../styles/
|
|
105
|
+
@use '../../styles/utils' as *;
|
|
99
106
|
|
|
100
107
|
.CheckboxGroup {
|
|
101
108
|
flex: 1;
|
|
@@ -4,11 +4,19 @@
|
|
|
4
4
|
v-for="(item, index) in options"
|
|
5
5
|
:key="index"
|
|
6
6
|
:value="
|
|
7
|
-
radio
|
|
7
|
+
radio
|
|
8
|
+
? item.value === currentValue
|
|
9
|
+
: Array.isArray(currentValue) &&
|
|
10
|
+
currentValue.includes(item.value)
|
|
8
11
|
"
|
|
9
12
|
:icon="icon"
|
|
10
|
-
:checked-icon="
|
|
11
|
-
|
|
13
|
+
:checked-icon="
|
|
14
|
+
checkedIcon || (radio ? 'radio-checked' : 'checkbox-checked')
|
|
15
|
+
"
|
|
16
|
+
:unchecked-icon="
|
|
17
|
+
uncheckedIcon ||
|
|
18
|
+
(radio ? 'radio-unchecked' : 'checkbox-unchecked')
|
|
19
|
+
"
|
|
12
20
|
:class="$style['CheckboxGroup2--item']"
|
|
13
21
|
@change="check(item.value)"
|
|
14
22
|
>
|
|
@@ -29,7 +37,7 @@ defineOptions({
|
|
|
29
37
|
},
|
|
30
38
|
});
|
|
31
39
|
|
|
32
|
-
const classNames = useClassNames('
|
|
40
|
+
const classNames = useClassNames('checkbox-group2');
|
|
33
41
|
|
|
34
42
|
type OptionValue = string | number | boolean;
|
|
35
43
|
interface _Option {
|
|
@@ -70,7 +78,9 @@ const checkedValue = ref<OptionValue | OptionValue[]>();
|
|
|
70
78
|
|
|
71
79
|
const currentValue = computed<undefined | OptionValue | OptionValue[]>({
|
|
72
80
|
get() {
|
|
73
|
-
return props.modelValue === undefined
|
|
81
|
+
return props.modelValue === undefined
|
|
82
|
+
? checkedValue.value
|
|
83
|
+
: props.modelValue;
|
|
74
84
|
},
|
|
75
85
|
set(val) {
|
|
76
86
|
emit('update:modelValue', val);
|
|
@@ -117,11 +127,16 @@ const toggle = (isSelectedAll: boolean | OptionValue | OptionValue[]) => {
|
|
|
117
127
|
}
|
|
118
128
|
|
|
119
129
|
if (Array.isArray(isSelectedAll)) {
|
|
120
|
-
currentValue.value = isSelectedAll.filter((item) =>
|
|
130
|
+
currentValue.value = isSelectedAll.filter((item) =>
|
|
131
|
+
optionsValue.value.includes(item)
|
|
132
|
+
);
|
|
121
133
|
return;
|
|
122
134
|
}
|
|
123
135
|
|
|
124
|
-
if (
|
|
136
|
+
if (
|
|
137
|
+
Array.isArray(currentValue.value) &&
|
|
138
|
+
currentValue.value.length === props.options.length
|
|
139
|
+
) {
|
|
125
140
|
currentValue.value = [];
|
|
126
141
|
} else {
|
|
127
142
|
currentValue.value = optionsValue.value;
|
|
@@ -132,7 +147,7 @@ defineExpose({ toggle });
|
|
|
132
147
|
</script>
|
|
133
148
|
|
|
134
149
|
<style lang="scss" module>
|
|
135
|
-
@use '../../styles/
|
|
150
|
+
@use '../../styles/utils' as *;
|
|
136
151
|
|
|
137
152
|
.CheckboxGroup2 {
|
|
138
153
|
display: flex;
|
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
<view :class="[...classNames, $style['Checkbox2']]" @click="toggle()">
|
|
3
3
|
<icon-cpn
|
|
4
4
|
v-if="icon"
|
|
5
|
-
:icon="
|
|
5
|
+
:icon="
|
|
6
|
+
currentValue
|
|
7
|
+
? checkedIcon || 'checkbox-checked'
|
|
8
|
+
: uncheckedIcon || 'checkbox-unchecked'
|
|
9
|
+
"
|
|
6
10
|
tap-size="50rpx"
|
|
7
|
-
:class="[
|
|
11
|
+
:class="[
|
|
12
|
+
$style['Checkbox2--icon'],
|
|
13
|
+
{ [$style['Checkbox2--checked']]: currentValue },
|
|
14
|
+
]"
|
|
8
15
|
/>
|
|
9
16
|
<view :class="$style['Checkbox2--text']">
|
|
10
17
|
<slot></slot>
|
|
@@ -24,7 +31,7 @@ defineOptions({
|
|
|
24
31
|
},
|
|
25
32
|
});
|
|
26
33
|
|
|
27
|
-
const classNames = useClassNames('
|
|
34
|
+
const classNames = useClassNames('checkbox2');
|
|
28
35
|
|
|
29
36
|
type _Props = {
|
|
30
37
|
/** 选项值 */
|
|
@@ -81,7 +88,7 @@ const toggle = (checked?: boolean) => {
|
|
|
81
88
|
|
|
82
89
|
// 定义外部变量
|
|
83
90
|
%external-vars {
|
|
84
|
-
@include UTILS__DEFINE_COMPONENT_VARS(
|
|
91
|
+
@include UTILS__DEFINE_COMPONENT_VARS('checkbox', $checkbox);
|
|
85
92
|
}
|
|
86
93
|
|
|
87
94
|
.Checkbox2 {
|
|
@@ -10,13 +10,23 @@
|
|
|
10
10
|
@load-more="$emit('load-more')"
|
|
11
11
|
/>
|
|
12
12
|
|
|
13
|
-
<view
|
|
13
|
+
<view
|
|
14
|
+
v-if="pagingData && pagingData.hasMore"
|
|
15
|
+
:class="$style['DataList--observe-view']"
|
|
16
|
+
></view>
|
|
14
17
|
</view>
|
|
15
18
|
</template>
|
|
16
19
|
|
|
17
20
|
<script lang="ts" setup>
|
|
18
|
-
import {
|
|
19
|
-
|
|
21
|
+
import {
|
|
22
|
+
getCurrentInstance,
|
|
23
|
+
onBeforeUnmount,
|
|
24
|
+
onMounted,
|
|
25
|
+
useCssModule,
|
|
26
|
+
watch,
|
|
27
|
+
} from 'vue';
|
|
28
|
+
import type { WatchStopHandle } from 'vue';
|
|
29
|
+
import type { PagingData } from '@ecolovo/utils';
|
|
20
30
|
import useClassNames from '../../composable/component-name';
|
|
21
31
|
import LoadMoreCpn from '../load-more/load-more.vue';
|
|
22
32
|
|
|
@@ -68,7 +78,7 @@ const stopObserver = () => {
|
|
|
68
78
|
_observer?.disconnect();
|
|
69
79
|
};
|
|
70
80
|
|
|
71
|
-
let _stopHasMoreWatcher:
|
|
81
|
+
let _stopHasMoreWatcher: WatchStopHandle | null = null;
|
|
72
82
|
|
|
73
83
|
onMounted(() => {
|
|
74
84
|
_stopHasMoreWatcher = watch(
|
|
@@ -94,7 +104,17 @@ onBeforeUnmount(() => {
|
|
|
94
104
|
|
|
95
105
|
// 定义外部变量
|
|
96
106
|
%external-vars {
|
|
97
|
-
@include UTILS__DEFINE_COMPONENT_VARS(
|
|
107
|
+
@include UTILS__DEFINE_COMPONENT_VARS('data-list', $data-list);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
:host {
|
|
111
|
+
position: relative;
|
|
112
|
+
display: block;
|
|
113
|
+
width: 100%;
|
|
114
|
+
|
|
115
|
+
flex: 1;
|
|
116
|
+
display: flex;
|
|
117
|
+
flex-direction: column;
|
|
98
118
|
}
|
|
99
119
|
|
|
100
120
|
.DataList {
|