@ecolovo/uniapp-components 2.0.2 → 2.0.3
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 +5 -0
- package/index.js +5 -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
|
@@ -7,17 +7,29 @@
|
|
|
7
7
|
@pickend="onPickEnd"
|
|
8
8
|
>
|
|
9
9
|
<picker-view-column>
|
|
10
|
-
<view
|
|
10
|
+
<view
|
|
11
|
+
v-for="item in yearOptions"
|
|
12
|
+
:key="item"
|
|
13
|
+
:class="$style['DatePickerView--option']"
|
|
14
|
+
>
|
|
11
15
|
{{ item }} 年
|
|
12
16
|
</view>
|
|
13
17
|
</picker-view-column>
|
|
14
18
|
<picker-view-column>
|
|
15
|
-
<view
|
|
19
|
+
<view
|
|
20
|
+
v-for="item in monthOptions"
|
|
21
|
+
:key="item"
|
|
22
|
+
:class="$style['DatePickerView--option']"
|
|
23
|
+
>
|
|
16
24
|
{{ item }} 月
|
|
17
25
|
</view>
|
|
18
26
|
</picker-view-column>
|
|
19
27
|
<picker-view-column>
|
|
20
|
-
<view
|
|
28
|
+
<view
|
|
29
|
+
v-for="item in dateOptions"
|
|
30
|
+
:key="item"
|
|
31
|
+
:class="$style['DatePickerView--option']"
|
|
32
|
+
>
|
|
21
33
|
{{ item }} 日
|
|
22
34
|
</view>
|
|
23
35
|
</picker-view-column>
|
|
@@ -26,7 +38,7 @@
|
|
|
26
38
|
|
|
27
39
|
<script lang="ts" setup>
|
|
28
40
|
import { computed, nextTick, onMounted, ref } from 'vue';
|
|
29
|
-
import range from 'lodash-es
|
|
41
|
+
import { range } from 'lodash-es';
|
|
30
42
|
import useClassNames from '../../composable/component-name';
|
|
31
43
|
import { formatDate, toDate } from '../../utils/date';
|
|
32
44
|
|
|
@@ -88,7 +100,8 @@ const dateOptions = ref<number[]>([]);
|
|
|
88
100
|
const pickerValue = ref<number[] | string[]>([0, 0, 0]);
|
|
89
101
|
|
|
90
102
|
const currentValue = computed({
|
|
91
|
-
get: () =>
|
|
103
|
+
get: () =>
|
|
104
|
+
props.modelValue === null ? innerValue.value : props.modelValue,
|
|
92
105
|
set: (val: string) => {
|
|
93
106
|
emit('update:modelValue', val);
|
|
94
107
|
innerValue.value = val;
|
|
@@ -111,7 +124,9 @@ const syncPickerValue = (date: Date | number | string) => {
|
|
|
111
124
|
const k = dateOptions.value.indexOf(Number(d));
|
|
112
125
|
nextTick(() => {
|
|
113
126
|
pickerValue.value =
|
|
114
|
-
typeof pickerValue.value[0] === 'number'
|
|
127
|
+
typeof pickerValue.value[0] === 'number'
|
|
128
|
+
? [i, j, k].map((item) => item.toString())
|
|
129
|
+
: [i, j, k];
|
|
115
130
|
});
|
|
116
131
|
};
|
|
117
132
|
|
|
@@ -119,14 +134,18 @@ const syncPickerValue = (date: Date | number | string) => {
|
|
|
119
134
|
const handlePickerChange = (e: Event) => {
|
|
120
135
|
const newPickerValue = (e as CustomEvent).detail.value as number[];
|
|
121
136
|
/** 获取变化的列 */
|
|
122
|
-
const col = pickerValue.value.findIndex(
|
|
137
|
+
const col = pickerValue.value.findIndex(
|
|
138
|
+
(item, index) => Number(item) !== Number(newPickerValue[index])
|
|
139
|
+
);
|
|
123
140
|
const year = yearOptions[newPickerValue[0]!]!;
|
|
124
141
|
const month = monthOptions[newPickerValue[1]!]!;
|
|
125
142
|
// 如果改变的是年份或月份,需要重新获取日期列表
|
|
126
143
|
if (col === 0 || col === 1) {
|
|
127
144
|
dateOptions.value = getDateOptions(toDate(`${year}-${month}-01`)!);
|
|
128
145
|
newPickerValue[2] = Math.min(
|
|
129
|
-
newPickerValue[2] === -1
|
|
146
|
+
newPickerValue[2] === -1
|
|
147
|
+
? dateOptions.value.length - 1
|
|
148
|
+
: newPickerValue[2]!,
|
|
130
149
|
dateOptions.value.length - 1
|
|
131
150
|
);
|
|
132
151
|
}
|
|
@@ -138,20 +157,30 @@ const handlePickerChange = (e: Event) => {
|
|
|
138
157
|
if (props.min && dateStr < props.min) {
|
|
139
158
|
let minDate: string;
|
|
140
159
|
|
|
141
|
-
if (props.min === 'today')
|
|
142
|
-
|
|
143
|
-
else if (props.min === '
|
|
144
|
-
|
|
160
|
+
if (props.min === 'today') {
|
|
161
|
+
minDate = formatDate(new Date());
|
|
162
|
+
} else if (props.min === 'tomorrow') {
|
|
163
|
+
minDate = formatDate(new Date(Date.now() + 8.64e7));
|
|
164
|
+
} else if (props.min === 'yesterday') {
|
|
165
|
+
minDate = formatDate(new Date(Date.now() - 8.64e7));
|
|
166
|
+
} else {
|
|
167
|
+
minDate = props.min;
|
|
168
|
+
}
|
|
145
169
|
|
|
146
170
|
dateStr = minDate;
|
|
147
171
|
}
|
|
148
172
|
if (props.max && dateStr > props.max) {
|
|
149
173
|
let maxDate: string;
|
|
150
174
|
|
|
151
|
-
if (props.max === 'today')
|
|
152
|
-
|
|
153
|
-
else if (props.max === '
|
|
154
|
-
|
|
175
|
+
if (props.max === 'today') {
|
|
176
|
+
maxDate = formatDate(new Date());
|
|
177
|
+
} else if (props.max === 'tomorrow') {
|
|
178
|
+
maxDate = formatDate(new Date(Date.now() + 8.64e7));
|
|
179
|
+
} else if (props.max === 'yesterday') {
|
|
180
|
+
maxDate = formatDate(new Date(Date.now() - 8.64e7));
|
|
181
|
+
} else {
|
|
182
|
+
maxDate = props.max;
|
|
183
|
+
}
|
|
155
184
|
|
|
156
185
|
dateStr = maxDate;
|
|
157
186
|
}
|
|
@@ -17,14 +17,17 @@
|
|
|
17
17
|
v-model="isShowPopup"
|
|
18
18
|
:cancel="false"
|
|
19
19
|
title="选择日期"
|
|
20
|
-
@click.stop.prevent
|
|
20
|
+
@click.stop.prevent
|
|
21
21
|
@confirm="onConfirm"
|
|
22
22
|
>
|
|
23
23
|
<view v-if="range" :class="$style['DatePicker--date-selector']">
|
|
24
24
|
<view
|
|
25
25
|
:class="[
|
|
26
26
|
$style['DatePicker--date-input'],
|
|
27
|
-
{
|
|
27
|
+
{
|
|
28
|
+
[$style['DatePicker--date-checked']]:
|
|
29
|
+
'start' === checkedDateType,
|
|
30
|
+
},
|
|
28
31
|
]"
|
|
29
32
|
@click="selectDateType('start')"
|
|
30
33
|
>
|
|
@@ -34,7 +37,10 @@
|
|
|
34
37
|
<view
|
|
35
38
|
:class="[
|
|
36
39
|
$style['DatePicker--date-input'],
|
|
37
|
-
{
|
|
40
|
+
{
|
|
41
|
+
[$style['DatePicker--date-checked']]:
|
|
42
|
+
'end' === checkedDateType,
|
|
43
|
+
},
|
|
38
44
|
]"
|
|
39
45
|
@click="selectDateType('end')"
|
|
40
46
|
>
|
|
@@ -43,10 +49,20 @@
|
|
|
43
49
|
</view>
|
|
44
50
|
|
|
45
51
|
<view v-show="checkedDateType === 'start'">
|
|
46
|
-
<date-picker-view-cpn
|
|
52
|
+
<date-picker-view-cpn
|
|
53
|
+
v-model="startStr"
|
|
54
|
+
:min="min"
|
|
55
|
+
:max="max"
|
|
56
|
+
@change="onChangeStart"
|
|
57
|
+
/>
|
|
47
58
|
</view>
|
|
48
59
|
<view v-if="range" v-show="checkedDateType === 'end'">
|
|
49
|
-
<date-picker-view-cpn
|
|
60
|
+
<date-picker-view-cpn
|
|
61
|
+
v-model="endStr"
|
|
62
|
+
:min="min"
|
|
63
|
+
:max="max"
|
|
64
|
+
@change="onChangeEnd"
|
|
65
|
+
/>
|
|
50
66
|
</view>
|
|
51
67
|
</popup-cpn>
|
|
52
68
|
</view>
|
|
@@ -132,20 +148,30 @@ const isReadonly = computed(() => props.readonly || isFormReadonly.value);
|
|
|
132
148
|
|
|
133
149
|
const startDate = computed(() => {
|
|
134
150
|
return formatDate(
|
|
135
|
-
toDate(
|
|
151
|
+
toDate(
|
|
152
|
+
props.range && Array.isArray(props.modelValue)
|
|
153
|
+
? props.modelValue[0]
|
|
154
|
+
: (props.modelValue as string)
|
|
155
|
+
)
|
|
136
156
|
);
|
|
137
157
|
});
|
|
138
158
|
|
|
139
159
|
const endDate = computed(() => {
|
|
140
|
-
return formatDate(
|
|
160
|
+
return formatDate(
|
|
161
|
+
toDate(
|
|
162
|
+
props.range && Array.isArray(props.modelValue)
|
|
163
|
+
? props.modelValue[1]
|
|
164
|
+
: ''
|
|
165
|
+
)
|
|
166
|
+
);
|
|
141
167
|
});
|
|
142
168
|
|
|
143
169
|
const showText = computed(() => {
|
|
144
|
-
return props.range && startDate.value && endDate.value
|
|
170
|
+
return props.range && startDate.value && endDate.value
|
|
171
|
+
? `${startDate.value} 至 ${endDate.value}`
|
|
172
|
+
: startDate.value;
|
|
145
173
|
});
|
|
146
174
|
|
|
147
|
-
const doNothing = () => {};
|
|
148
|
-
|
|
149
175
|
/** 显示选择器弹出框 */
|
|
150
176
|
const showPicker = () => {
|
|
151
177
|
if (props.disabled || isReadonly.value) {
|
|
@@ -156,7 +182,8 @@ const showPicker = () => {
|
|
|
156
182
|
|
|
157
183
|
const [start, end] = [startDate.value, endDate.value];
|
|
158
184
|
startStr.value = start || formatDate(new Date());
|
|
159
|
-
endStr.value =
|
|
185
|
+
endStr.value =
|
|
186
|
+
end || formatDate(new Date(Date.now() + (props.canSame ? 0 : 8.64e7)));
|
|
160
187
|
|
|
161
188
|
isShowPopup.value = true;
|
|
162
189
|
emit('show');
|
|
@@ -170,12 +197,17 @@ const selectDateType = (type: 'start' | 'end') => {
|
|
|
170
197
|
const onChangeStart = (dateStr: string) => {
|
|
171
198
|
if (!props.range) return;
|
|
172
199
|
|
|
173
|
-
const timeDiff =
|
|
200
|
+
const timeDiff =
|
|
201
|
+
toDate(endStr.value)!.getTime() - toDate(dateStr)!.getTime();
|
|
174
202
|
if (endStr.value <= dateStr || props.keepDiff) {
|
|
175
203
|
if (props.keepDiff) {
|
|
176
|
-
endStr.value = formatDate(
|
|
204
|
+
endStr.value = formatDate(
|
|
205
|
+
new Date(toDate(dateStr)!.getTime() + timeDiff)
|
|
206
|
+
);
|
|
177
207
|
} else if (!props.canSame) {
|
|
178
|
-
endStr.value = formatDate(
|
|
208
|
+
endStr.value = formatDate(
|
|
209
|
+
new Date(toDate(dateStr)!.getTime() + 8.64e7)
|
|
210
|
+
);
|
|
179
211
|
} else {
|
|
180
212
|
endStr.value = dateStr;
|
|
181
213
|
}
|
|
@@ -187,16 +219,24 @@ const onChangeEnd = (dateStr: string) => {
|
|
|
187
219
|
if (props.canSame) {
|
|
188
220
|
endStr.value = startStr.value;
|
|
189
221
|
} else {
|
|
190
|
-
endStr.value = formatDate(
|
|
222
|
+
endStr.value = formatDate(
|
|
223
|
+
new Date(toDate(startStr.value)!.getTime() + 8.64e7)
|
|
224
|
+
);
|
|
191
225
|
}
|
|
192
226
|
}
|
|
193
227
|
};
|
|
194
228
|
|
|
195
229
|
const onConfirm = () => {
|
|
196
230
|
popupRef.value?.close();
|
|
197
|
-
const startAppend = Array.isArray(props.timeAppend)
|
|
198
|
-
|
|
199
|
-
|
|
231
|
+
const startAppend = Array.isArray(props.timeAppend)
|
|
232
|
+
? props.timeAppend[0]
|
|
233
|
+
: props.timeAppend;
|
|
234
|
+
const endAppend = Array.isArray(props.timeAppend)
|
|
235
|
+
? props.timeAppend[1]
|
|
236
|
+
: props.timeAppend;
|
|
237
|
+
const start = startAppend
|
|
238
|
+
? `${startStr.value} ${startAppend}`
|
|
239
|
+
: startStr.value;
|
|
200
240
|
const end = endAppend ? `${endStr.value} ${endAppend}` : endStr.value;
|
|
201
241
|
const result = props.range ? ([start, end] as [string, string]) : start;
|
|
202
242
|
emit('update:modelValue', result);
|
|
@@ -4,18 +4,28 @@
|
|
|
4
4
|
<!-- 内容上方标题 -->
|
|
5
5
|
<template #header>
|
|
6
6
|
<slot v-if="$slots.header" name="header"></slot>
|
|
7
|
-
<view
|
|
7
|
+
<view
|
|
8
|
+
v-else-if="title || showClose"
|
|
9
|
+
:class="$style['DialogContent--header']"
|
|
10
|
+
>
|
|
8
11
|
<view
|
|
9
12
|
:class="[
|
|
10
13
|
$style['DialogContent--title'],
|
|
11
|
-
{
|
|
14
|
+
{
|
|
15
|
+
[$style['DialogContent--title-center']]:
|
|
16
|
+
centerTitle,
|
|
17
|
+
},
|
|
12
18
|
]"
|
|
13
19
|
>
|
|
14
20
|
<slot name="title">
|
|
15
21
|
<text>{{ title }}</text>
|
|
16
22
|
</slot>
|
|
17
23
|
</view>
|
|
18
|
-
<view
|
|
24
|
+
<view
|
|
25
|
+
v-if="showClose"
|
|
26
|
+
:class="$style['DialogContent--close']"
|
|
27
|
+
@click="$emit('close')"
|
|
28
|
+
>
|
|
19
29
|
<icon-cpn icon="close" tap-size="80rpx" />
|
|
20
30
|
</view>
|
|
21
31
|
</view>
|
|
@@ -27,15 +37,24 @@
|
|
|
27
37
|
<!-- 内容下方操作按钮 -->
|
|
28
38
|
<template #footer>
|
|
29
39
|
<slot v-if="$slots.footer" name="footer"></slot>
|
|
30
|
-
<view
|
|
31
|
-
|
|
40
|
+
<view
|
|
41
|
+
v-else-if="cancel || confirm"
|
|
42
|
+
:class="$style['DialogContent--footer']"
|
|
43
|
+
>
|
|
44
|
+
<view
|
|
45
|
+
v-if="cancel"
|
|
46
|
+
:class="$style['DialogContent--button']"
|
|
47
|
+
>
|
|
32
48
|
<slot name="cancel">
|
|
33
49
|
<button-cpn plain @click="$emit('cancel')">
|
|
34
50
|
{{ cancel }}
|
|
35
51
|
</button-cpn>
|
|
36
52
|
</slot>
|
|
37
53
|
</view>
|
|
38
|
-
<view
|
|
54
|
+
<view
|
|
55
|
+
v-if="confirm"
|
|
56
|
+
:class="$style['DialogContent--button']"
|
|
57
|
+
>
|
|
39
58
|
<slot name="confirm">
|
|
40
59
|
<button-cpn @click="$emit('confirm')">
|
|
41
60
|
{{ confirm }}
|
|
@@ -100,14 +119,22 @@ defineEmits<{
|
|
|
100
119
|
|
|
101
120
|
// 定义外部变量
|
|
102
121
|
%external-vars {
|
|
103
|
-
@include UTILS__DEFINE_COMPONENT_VARS(
|
|
122
|
+
@include UTILS__DEFINE_COMPONENT_VARS('dialog', $dialog);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
:host {
|
|
126
|
+
display: block;
|
|
104
127
|
}
|
|
105
128
|
|
|
106
129
|
.DialogContent {
|
|
107
130
|
@extend %external-vars;
|
|
108
|
-
#{UTILS__VAR_NAME(header-height
|
|
109
|
-
|
|
110
|
-
|
|
131
|
+
#{UTILS__VAR_NAME(popover, header-height)}: #{UTILS__LOCAL_VAR(
|
|
132
|
+
header-height
|
|
133
|
+
)};
|
|
134
|
+
#{UTILS__VAR_NAME(popover, footer-height)}: #{UTILS__LOCAL_VAR(
|
|
135
|
+
footer-height
|
|
136
|
+
)};
|
|
137
|
+
#{UTILS__VAR_NAME(popover, padding)}: 20rpx 30rpx;
|
|
111
138
|
|
|
112
139
|
.DialogContent--header {
|
|
113
140
|
position: relative;
|
|
@@ -148,8 +175,8 @@ defineEmits<{
|
|
|
148
175
|
}
|
|
149
176
|
.DialogContent--button {
|
|
150
177
|
flex: 1;
|
|
151
|
-
#{UTILS__VAR_NAME(
|
|
152
|
-
#{UTILS__VAR_NAME(border-radius
|
|
178
|
+
#{UTILS__VAR_NAME(button, height)}: 84rpx;
|
|
179
|
+
#{UTILS__VAR_NAME(button, border-radius)}: 20rpx;
|
|
153
180
|
& + #{UTILS__LAST_SELECTOR(&)} {
|
|
154
181
|
margin-left: 20rpx;
|
|
155
182
|
}
|
|
@@ -86,7 +86,10 @@ const emit = defineEmits<{
|
|
|
86
86
|
(e: 'close'): void;
|
|
87
87
|
(e: 'closed'): void;
|
|
88
88
|
(e: 'cancel', closeFn?: VoidFunction): void;
|
|
89
|
-
(
|
|
89
|
+
(
|
|
90
|
+
e: 'confirm',
|
|
91
|
+
payload?: UniApp.PromiseResolvers<unknown> | VoidFunction
|
|
92
|
+
): void;
|
|
90
93
|
}>();
|
|
91
94
|
|
|
92
95
|
const isAsyncLoading = ref(false);
|
|
@@ -105,24 +108,34 @@ const onClose = () => {
|
|
|
105
108
|
close();
|
|
106
109
|
};
|
|
107
110
|
|
|
111
|
+
/** 点击取消按钮响应 */
|
|
108
112
|
const onCancel = () => {
|
|
109
|
-
|
|
110
|
-
};
|
|
113
|
+
if (isLoading.value) return;
|
|
111
114
|
|
|
112
|
-
|
|
113
|
-
|
|
115
|
+
if (props.closeOnCancel) {
|
|
116
|
+
emit('cancel');
|
|
117
|
+
close();
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
emit('cancel', maskRef.value?.close.bind(maskRef.value));
|
|
114
122
|
};
|
|
115
123
|
|
|
116
|
-
/**
|
|
117
|
-
|
|
118
|
-
* @param {boolean} shouldClose 是否自动关闭对话框
|
|
119
|
-
*/
|
|
120
|
-
const onButton = (btnType: 'cancel' | 'confirm', shouldClose: boolean) => {
|
|
124
|
+
/** 点击确认按钮响应 */
|
|
125
|
+
const onConfirm = () => {
|
|
121
126
|
if (isLoading.value) return;
|
|
122
127
|
|
|
123
|
-
if (
|
|
128
|
+
if (props.async) {
|
|
124
129
|
isAsyncLoading.value = true;
|
|
125
|
-
|
|
130
|
+
|
|
131
|
+
// const { promise, resolve, reject } = Promise.withResolvers();
|
|
132
|
+
let resolve: UniApp.PromiseResolver<unknown>,
|
|
133
|
+
reject: UniApp.PromiseRejector<unknown>;
|
|
134
|
+
const promise = new Promise((res, rej) => {
|
|
135
|
+
resolve = res;
|
|
136
|
+
reject = rej;
|
|
137
|
+
});
|
|
138
|
+
|
|
126
139
|
promise
|
|
127
140
|
.then((willClose = true) => {
|
|
128
141
|
if (willClose === false) {
|
|
@@ -138,24 +151,22 @@ const onButton = (btnType: 'cancel' | 'confirm', shouldClose: boolean) => {
|
|
|
138
151
|
}
|
|
139
152
|
isAsyncLoading.value = false;
|
|
140
153
|
});
|
|
141
|
-
emit(
|
|
154
|
+
emit('confirm', { resolve, reject });
|
|
142
155
|
return;
|
|
143
156
|
}
|
|
144
157
|
|
|
145
|
-
if (
|
|
146
|
-
|
|
147
|
-
emit(btnType);
|
|
158
|
+
if (props.closeOnConfirm) {
|
|
159
|
+
emit('confirm');
|
|
148
160
|
close();
|
|
149
161
|
return;
|
|
150
162
|
}
|
|
151
163
|
|
|
152
|
-
|
|
153
|
-
emit(btnType, maskRef.value?.close.bind(maskRef.value));
|
|
164
|
+
emit('confirm', maskRef.value?.close.bind(maskRef.value));
|
|
154
165
|
};
|
|
155
166
|
|
|
156
167
|
defineExpose({ close });
|
|
157
168
|
</script>
|
|
158
169
|
|
|
159
170
|
<style lang="scss" module>
|
|
160
|
-
@use '../../styles/
|
|
171
|
+
@use '../../styles/utils' as *;
|
|
161
172
|
</style>
|
|
@@ -3,13 +3,24 @@
|
|
|
3
3
|
<view
|
|
4
4
|
:class="[
|
|
5
5
|
$style['Dropdown--input'],
|
|
6
|
-
{
|
|
6
|
+
{
|
|
7
|
+
[$style['Dropdown--placeholder']]: !hasValue,
|
|
8
|
+
[$style['Dropdown--multiple']]: hasValue,
|
|
9
|
+
},
|
|
7
10
|
]"
|
|
8
11
|
>
|
|
9
|
-
<view
|
|
12
|
+
<view
|
|
13
|
+
:class="[
|
|
14
|
+
$style['Dropdown--ellipsis'],
|
|
15
|
+
{ [$style['Dropdown--expand']]: align !== 'center' },
|
|
16
|
+
]"
|
|
17
|
+
>
|
|
10
18
|
{{ showValue }}
|
|
11
19
|
</view>
|
|
12
|
-
<icon-cpn
|
|
20
|
+
<icon-cpn
|
|
21
|
+
icon="triangle-down"
|
|
22
|
+
:class="$style['Dropdown--icon']"
|
|
23
|
+
></icon-cpn>
|
|
13
24
|
</view>
|
|
14
25
|
</view>
|
|
15
26
|
</template>
|
|
@@ -51,7 +62,10 @@ const props = withDefaults(defineProps<_Props>(), {
|
|
|
51
62
|
|
|
52
63
|
/** 是否选择了值 */
|
|
53
64
|
const hasValue = computed(() => {
|
|
54
|
-
return
|
|
65
|
+
return (
|
|
66
|
+
props.modelValue !== null &&
|
|
67
|
+
(!Array.isArray(props.modelValue) || props.modelValue.length > 0)
|
|
68
|
+
);
|
|
55
69
|
});
|
|
56
70
|
|
|
57
71
|
/** 展示值 */
|
|
@@ -59,7 +73,9 @@ const showValue = computed(() => {
|
|
|
59
73
|
if (!hasValue.value) return props.placeholder;
|
|
60
74
|
return props.formatter
|
|
61
75
|
? props.formatter(props.modelValue)
|
|
62
|
-
: props.multiple &&
|
|
76
|
+
: props.multiple &&
|
|
77
|
+
Array.isArray(props.modelValue) &&
|
|
78
|
+
props.modelValue.length > 1
|
|
63
79
|
? `+${props.modelValue.length}`
|
|
64
80
|
: props.modelValue;
|
|
65
81
|
});
|
|
@@ -69,8 +85,9 @@ const showValue = computed(() => {
|
|
|
69
85
|
@use '../../styles/utils' as *;
|
|
70
86
|
@use './dropdown' as *;
|
|
71
87
|
|
|
88
|
+
// 定义外部变量
|
|
72
89
|
%external-vars {
|
|
73
|
-
@include UTILS__DEFINE_COMPONENT_VARS(
|
|
90
|
+
@include UTILS__DEFINE_COMPONENT_VARS('dropdown', $dropdown);
|
|
74
91
|
}
|
|
75
92
|
|
|
76
93
|
.Dropdown {
|
|
@@ -89,6 +106,12 @@ const showValue = computed(() => {
|
|
|
89
106
|
background: UTILS__LOCAL_VAR(input-background);
|
|
90
107
|
border-radius: UTILS__LOCAL_VAR(input-radius);
|
|
91
108
|
}
|
|
109
|
+
.Dropdown--ellipsis {
|
|
110
|
+
@include UTILS__ELLIPSIS;
|
|
111
|
+
}
|
|
112
|
+
.Dropdown--expand {
|
|
113
|
+
flex: 1;
|
|
114
|
+
}
|
|
92
115
|
.Dropdown--placeholder {
|
|
93
116
|
color: UTILS__GLOBAL_VAR(color, placeholder);
|
|
94
117
|
}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<view :class="[...classNames, $style['Empty']]">
|
|
3
3
|
<template v-if="loading">
|
|
4
|
-
<image
|
|
4
|
+
<image
|
|
5
|
+
v-if="loadingImage"
|
|
6
|
+
:src="loadingImage"
|
|
7
|
+
:class="$style['Empty--image']"
|
|
8
|
+
/>
|
|
5
9
|
<view v-else :class="$style['Empty--loading-icon-wrapper']">
|
|
6
|
-
<icon-cpn
|
|
10
|
+
<icon-cpn
|
|
11
|
+
icon="search"
|
|
12
|
+
:class="$style['Empty--loading-icon']"
|
|
13
|
+
/>
|
|
7
14
|
</view>
|
|
8
15
|
<view :class="$style['Empty--text']">
|
|
9
16
|
<slot>{{ loadingText }}</slot>
|
|
@@ -61,7 +68,7 @@ withDefaults(defineProps<_Props>(), {
|
|
|
61
68
|
|
|
62
69
|
// 定义外部变量
|
|
63
70
|
%external-vars {
|
|
64
|
-
@include UTILS__DEFINE_COMPONENT_VARS(
|
|
71
|
+
@include UTILS__DEFINE_COMPONENT_VARS('empty', $empty);
|
|
65
72
|
}
|
|
66
73
|
|
|
67
74
|
.Empty {
|
package/components/flex/flex.vue
CHANGED
|
@@ -21,7 +21,13 @@ type _Props = {
|
|
|
21
21
|
/** 排版方向 */
|
|
22
22
|
direction?: 'row' | 'row-reverse' | 'column' | 'column-reverse';
|
|
23
23
|
/** 当前轴对齐方式 */
|
|
24
|
-
justify?:
|
|
24
|
+
justify?:
|
|
25
|
+
| 'start'
|
|
26
|
+
| 'center'
|
|
27
|
+
| 'end'
|
|
28
|
+
| 'space-between'
|
|
29
|
+
| 'space-around'
|
|
30
|
+
| 'space-evenly';
|
|
25
31
|
/** 交叉轴对齐方式 */
|
|
26
32
|
align?: 'start' | 'center' | 'end' | 'baseline' | 'stretch';
|
|
27
33
|
/** 是否换行 */
|
|
@@ -40,9 +46,15 @@ const props = withDefaults(defineProps<_Props>(), {
|
|
|
40
46
|
|
|
41
47
|
const gapValue = computed(() => {
|
|
42
48
|
if (Array.isArray(props.gap)) {
|
|
43
|
-
return props.gap
|
|
49
|
+
return props.gap
|
|
50
|
+
.map((item) =>
|
|
51
|
+
typeof item === 'number' ? uni.upx2px(item) + 'px' : item
|
|
52
|
+
)
|
|
53
|
+
.join(' ');
|
|
44
54
|
}
|
|
45
|
-
return typeof props.gap === 'number'
|
|
55
|
+
return typeof props.gap === 'number'
|
|
56
|
+
? uni.upx2px(props.gap) + 'px'
|
|
57
|
+
: props.gap;
|
|
46
58
|
});
|
|
47
59
|
|
|
48
60
|
const flexStyle = computed(() => {
|
|
@@ -57,11 +69,9 @@ const flexStyle = computed(() => {
|
|
|
57
69
|
</script>
|
|
58
70
|
|
|
59
71
|
<style lang="scss" module>
|
|
60
|
-
@use '../../styles/
|
|
72
|
+
@use '../../styles/utils' as *;
|
|
61
73
|
|
|
62
74
|
.Flex {
|
|
63
|
-
width: 100%;
|
|
64
|
-
height: 100%;
|
|
65
75
|
display: flex;
|
|
66
76
|
}
|
|
67
77
|
</style>
|
|
@@ -11,8 +11,15 @@
|
|
|
11
11
|
]"
|
|
12
12
|
>
|
|
13
13
|
<view :class="$style['FormItem--label']">
|
|
14
|
-
<text
|
|
15
|
-
|
|
14
|
+
<text
|
|
15
|
+
:class="{
|
|
16
|
+
[$style['FormItem--required']]: !isFormReadonly && required,
|
|
17
|
+
}"
|
|
18
|
+
>{{ label }}</text
|
|
19
|
+
>
|
|
20
|
+
<text v-if="subLabel" :class="$style['FormItem--sub-label']">{{
|
|
21
|
+
subLabel
|
|
22
|
+
}}</text>
|
|
16
23
|
</view>
|
|
17
24
|
<view :class="$style['FormItem--content']">
|
|
18
25
|
<slot></slot>
|
|
@@ -21,7 +28,8 @@
|
|
|
21
28
|
</template>
|
|
22
29
|
|
|
23
30
|
<script lang="ts" setup>
|
|
24
|
-
import { computed,
|
|
31
|
+
import { computed, inject } from 'vue';
|
|
32
|
+
import type { ComputedRef } from 'vue';
|
|
25
33
|
import useClassNames from '../../composable/component-name';
|
|
26
34
|
|
|
27
35
|
defineOptions({
|
|
@@ -70,8 +78,9 @@ const usingType = computed(() => props.type || formType.value);
|
|
|
70
78
|
@use '../../styles/utils' as *;
|
|
71
79
|
@use './form-item' as *;
|
|
72
80
|
|
|
81
|
+
// 定义外部变量
|
|
73
82
|
%external-vars {
|
|
74
|
-
@include UTILS__DEFINE_COMPONENT_VARS(
|
|
83
|
+
@include UTILS__DEFINE_COMPONENT_VARS('form-item', $form-item);
|
|
75
84
|
}
|
|
76
85
|
|
|
77
86
|
.FormItem {
|