uview-pro 0.3.5 → 0.3.7
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/changelog.md +46 -0
- package/components/u-calendar/types.ts +3 -2
- package/components/u-calendar/u-calendar.vue +2 -2
- package/components/u-checkbox/u-checkbox.vue +1 -1
- package/components/u-checkbox-group/types.ts +2 -1
- package/components/u-checkbox-group/u-checkbox-group.vue +1 -1
- package/components/u-city-select/u-city-select.vue +2 -2
- package/components/u-dropdown/types.ts +3 -2
- package/components/u-dropdown/u-dropdown.vue +1 -1
- package/components/u-form/u-form.vue +14 -9
- package/components/u-form-item/u-form-item.vue +9 -6
- package/components/u-index-anchor/u-index-anchor.vue +1 -1
- package/components/u-index-list/types.ts +2 -1
- package/components/u-index-list/u-index-list.vue +3 -3
- package/components/u-input/types.ts +5 -0
- package/components/u-input/u-input.vue +28 -8
- package/components/u-link/types.ts +2 -1
- package/components/u-message-input/types.ts +3 -2
- package/components/u-message-input/u-message-input.vue +1 -1
- package/components/u-modal/types.ts +3 -2
- package/components/u-modal/u-modal.vue +1 -1
- package/components/u-picker/types.ts +8 -2
- package/components/u-picker/u-picker.vue +276 -126
- package/components/u-radio/u-radio.vue +2 -2
- package/components/u-radio-group/types.ts +2 -1
- package/components/u-radio-group/u-radio-group.vue +1 -1
- package/components/u-read-more/types.ts +2 -1
- package/components/u-read-more/u-read-more.vue +1 -1
- package/components/u-select/types.ts +5 -2
- package/components/u-select/u-select.vue +56 -18
- package/components/u-slider/types.ts +3 -2
- package/components/u-slider/u-slider.vue +2 -2
- package/components/u-step/types.ts +29 -0
- package/components/u-step/u-step.vue +264 -0
- package/components/u-steps/types.ts +3 -2
- package/components/u-steps/u-steps.vue +17 -106
- package/components/u-switch/types.ts +2 -1
- package/components/u-switch/u-switch.vue +2 -2
- package/components/u-tabs/types.ts +3 -2
- package/components/u-tabs/u-tabs.vue +1 -1
- package/components/u-tabs-swiper/types.ts +3 -2
- package/components/u-tabs-swiper/u-tabs-swiper.vue +1 -1
- package/components/u-textarea/types.ts +88 -0
- package/components/u-textarea/u-textarea.vue +339 -0
- package/package.json +1 -1
- package/types/components.d.ts +2 -0
- package/types/global.d.ts +2 -0
|
@@ -30,9 +30,7 @@
|
|
|
30
30
|
>
|
|
31
31
|
{{ cancelText }}
|
|
32
32
|
</view>
|
|
33
|
-
<view class="u-select__header__title">
|
|
34
|
-
{{ title }}
|
|
35
|
-
</view>
|
|
33
|
+
<view class="u-select__header__title u-line-1"> {{ title }}</view>
|
|
36
34
|
<view
|
|
37
35
|
class="u-select__header__confirm u-select__header__btn"
|
|
38
36
|
:style="{ color: moving ? cancelColor : confirmColor }"
|
|
@@ -51,7 +49,7 @@
|
|
|
51
49
|
:value="defaultSelector"
|
|
52
50
|
@pickstart="pickstart"
|
|
53
51
|
@pickend="pickend"
|
|
54
|
-
v-if="modelValue"
|
|
52
|
+
v-if="modelValue && readyToRender"
|
|
55
53
|
>
|
|
56
54
|
<picker-view-column v-for="(item, index) in columnData" :key="index">
|
|
57
55
|
<view
|
|
@@ -83,7 +81,7 @@ export default {
|
|
|
83
81
|
</script>
|
|
84
82
|
|
|
85
83
|
<script setup lang="ts">
|
|
86
|
-
import { ref, computed, watch } from 'vue';
|
|
84
|
+
import { ref, computed, watch, nextTick } from 'vue';
|
|
87
85
|
import { SelectProps } from './types';
|
|
88
86
|
import type { SelectListItem } from '../../types/global';
|
|
89
87
|
import { $u } from '../..';
|
|
@@ -97,7 +95,7 @@ import { $u } from '../..';
|
|
|
97
95
|
* @property {Boolean} v-model 布尔值变量,用于控制选择器的弹出与收起
|
|
98
96
|
* @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false)
|
|
99
97
|
* @property {String} cancel-color 取消按钮的颜色(默认#606266)
|
|
100
|
-
* @property {String} confirm-color 确认按钮的颜色(
|
|
98
|
+
* @property {String} confirm-color 确认按钮的颜色(默认主题色primary)
|
|
101
99
|
* @property {String} confirm-text 确认按钮的文字
|
|
102
100
|
* @property {String} cancel-text 取消按钮的文字
|
|
103
101
|
* @property {String} default-value 提供的默认选中的下标,见官网说明
|
|
@@ -117,6 +115,12 @@ const emit = defineEmits(['update:modelValue', 'confirm', 'cancel', 'click']);
|
|
|
117
115
|
const defaultSelector = ref<number[]>([0]);
|
|
118
116
|
// picker-view的数据
|
|
119
117
|
const columnData = ref<SelectListItem[][]>([]);
|
|
118
|
+
// 控制 picker 是否渲染(等待初始化完成)
|
|
119
|
+
const readyToRender = ref(false);
|
|
120
|
+
// 保存用户上次确认的索引,如果用户未确认过,则为 null,首次打开会使用 props.defaultValue
|
|
121
|
+
const savedSelector = ref<number[] | null>(
|
|
122
|
+
props.defaultValue && props.defaultValue.length ? props.defaultValue.slice() : null
|
|
123
|
+
);
|
|
120
124
|
// 每次队列发生变化时,保存选择的结果
|
|
121
125
|
const selectValue = ref<SelectListItem[]>([]);
|
|
122
126
|
// 上一次列变化时的index
|
|
@@ -135,8 +139,21 @@ const popupValue = computed({
|
|
|
135
139
|
|
|
136
140
|
watch(
|
|
137
141
|
() => props.modelValue,
|
|
138
|
-
val => {
|
|
139
|
-
if (val)
|
|
142
|
+
async val => {
|
|
143
|
+
if (val) {
|
|
144
|
+
// 等待一次 DOM 更新
|
|
145
|
+
await nextTick();
|
|
146
|
+
// 在 App(APP-PLUS)平台上,原生 picker 可能需要更长时间初始化
|
|
147
|
+
// 我们先执行 init,并在 init 完成后将 readyToRender 置为 true,保证 picker 在数据就绪后渲染
|
|
148
|
+
// #ifdef APP-PLUS
|
|
149
|
+
await new Promise(resolve => setTimeout(resolve, 20));
|
|
150
|
+
// #endif
|
|
151
|
+
init();
|
|
152
|
+
readyToRender.value = true;
|
|
153
|
+
} else {
|
|
154
|
+
// 关闭弹窗时复位
|
|
155
|
+
readyToRender.value = false;
|
|
156
|
+
}
|
|
140
157
|
},
|
|
141
158
|
{ immediate: true }
|
|
142
159
|
);
|
|
@@ -153,17 +170,31 @@ function pickend() {
|
|
|
153
170
|
}
|
|
154
171
|
|
|
155
172
|
function init() {
|
|
173
|
+
// 先计算列数
|
|
156
174
|
setColumnNum();
|
|
175
|
+
// 根据 columnData 和 columnNum 设置默认选中
|
|
157
176
|
setDefaultSelector();
|
|
177
|
+
// 准备列数据(部分模式需要依赖 defaultSelector 的值,但我们将先生成columnData的结构)
|
|
158
178
|
setColumnData();
|
|
179
|
+
// 清空并设置 selectValue
|
|
180
|
+
selectValue.value = [];
|
|
159
181
|
setSelectValue();
|
|
160
182
|
}
|
|
161
183
|
|
|
162
184
|
// 获取默认选中列下标
|
|
163
185
|
function setDefaultSelector() {
|
|
164
|
-
//
|
|
186
|
+
// 根据 preserveSelection 决定优先级:
|
|
187
|
+
// - 如果 preserveSelection 为 true(默认),优先使用用户已确认的选择 savedSelector(如果存在),否则使用 props.defaultValue
|
|
188
|
+
// - 如果 preserveSelection 为 false,则优先使用外部 props.defaultValue(如果存在),否则使用 savedSelector
|
|
189
|
+
let useDefault: number[] | null = null;
|
|
190
|
+
if (props.preserveSelection) {
|
|
191
|
+
useDefault = savedSelector.value && savedSelector.value.length ? savedSelector.value : props.defaultValue;
|
|
192
|
+
} else {
|
|
193
|
+
useDefault = props.defaultValue && props.defaultValue.length ? props.defaultValue : savedSelector.value;
|
|
194
|
+
}
|
|
195
|
+
// 如果没有传入默认选中的值,生成长度为 columnNum,用0填充的数组
|
|
165
196
|
defaultSelector.value =
|
|
166
|
-
|
|
197
|
+
useDefault && useDefault.length == columnNum.value ? useDefault.slice() : Array(columnNum.value).fill(0);
|
|
167
198
|
lastSelectIndex.value = [...defaultSelector.value];
|
|
168
199
|
}
|
|
169
200
|
// 计算列数
|
|
@@ -299,7 +330,7 @@ function columnChange(e: any) {
|
|
|
299
330
|
function close() {
|
|
300
331
|
emit('update:modelValue', false);
|
|
301
332
|
// 重置default-value默认值
|
|
302
|
-
defaultSelector.value = [0];
|
|
333
|
+
// defaultSelector.value = [0];
|
|
303
334
|
}
|
|
304
335
|
// 点击确定或者取消
|
|
305
336
|
function getResult(event: 'update:modelValue' | 'confirm' | 'cancel' | 'click' | null = null) {
|
|
@@ -308,6 +339,11 @@ function getResult(event: 'update:modelValue' | 'confirm' | 'cancel' | 'click' |
|
|
|
308
339
|
// #endif
|
|
309
340
|
|
|
310
341
|
if (event) emit(event, selectValue.value);
|
|
342
|
+
// 如果是用户确认,则保存已确认的索引,作为下次打开时的默认值
|
|
343
|
+
if (event === 'confirm') {
|
|
344
|
+
// deep copy
|
|
345
|
+
savedSelector.value = defaultSelector.value ? defaultSelector.value.slice() : null;
|
|
346
|
+
}
|
|
311
347
|
close();
|
|
312
348
|
}
|
|
313
349
|
|
|
@@ -344,12 +380,6 @@ function is2DList(list: SelectListItem[] | SelectListItem[][]): list is SelectLi
|
|
|
344
380
|
}
|
|
345
381
|
}
|
|
346
382
|
|
|
347
|
-
&__hader {
|
|
348
|
-
&__title {
|
|
349
|
-
color: $u-content-color;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
383
|
&--border {
|
|
354
384
|
border-radius: 6rpx;
|
|
355
385
|
border-radius: 4px;
|
|
@@ -361,7 +391,15 @@ function is2DList(list: SelectListItem[] | SelectListItem[][]): list is SelectLi
|
|
|
361
391
|
align-items: center;
|
|
362
392
|
justify-content: space-between;
|
|
363
393
|
height: 80rpx;
|
|
364
|
-
|
|
394
|
+
|
|
395
|
+
&__title {
|
|
396
|
+
color: $u-content-color;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
&__btn {
|
|
400
|
+
min-width: 150rpx;
|
|
401
|
+
padding: 20rpx 30rpx;
|
|
402
|
+
}
|
|
365
403
|
}
|
|
366
404
|
|
|
367
405
|
&__body {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ExtractPropTypes, PropType } from 'vue';
|
|
2
2
|
import { baseProps } from '../common/props';
|
|
3
|
+
import { $u } from '../../';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* SliderProps 滑块选择器 props 类型定义
|
|
@@ -22,9 +23,9 @@ export const SliderProps = {
|
|
|
22
23
|
/** 滑块条高度,单位rpx */
|
|
23
24
|
height: { type: [Number, String] as PropType<number | string>, default: 6 },
|
|
24
25
|
/** 进度条的激活部分颜色 */
|
|
25
|
-
activeColor: { type: String, default:
|
|
26
|
+
activeColor: { type: String, default: $u.color.primary },
|
|
26
27
|
/** 进度条的背景颜色 */
|
|
27
|
-
inactiveColor: { type: String, default:
|
|
28
|
+
inactiveColor: { type: String, default: $u.color.lightColor },
|
|
28
29
|
/** 滑块的背景颜色 */
|
|
29
30
|
blockColor: { type: String, default: '#ffffff' },
|
|
30
31
|
/** 用户对滑块的自定义颜色 */
|
|
@@ -66,7 +66,7 @@ import { SliderProps } from './types';
|
|
|
66
66
|
* @property {Number | String} blockWidth 滑块宽度,高等于宽(30)
|
|
67
67
|
* @property {Number | String} height 滑块条高度,单位rpx(默认6)
|
|
68
68
|
* @property {String} inactiveColor 底部条背景颜色(默认#c0c4cc)
|
|
69
|
-
* @property {String} activeColor
|
|
69
|
+
* @property {String} activeColor 底部选择部分的背景颜色(默认主题色primary)
|
|
70
70
|
* @property {String} blockColor 滑块颜色(默认#ffffff)
|
|
71
71
|
* @property {Object} blockStyle 给滑块自定义样式,对象形式
|
|
72
72
|
* @property {Boolean} disabled 是否禁用滑块(默认为false)
|
|
@@ -230,7 +230,7 @@ function onClick(event: any) {
|
|
|
230
230
|
position: relative;
|
|
231
231
|
border-radius: inherit;
|
|
232
232
|
transition: width 0.2s;
|
|
233
|
-
background-color:
|
|
233
|
+
background-color: $u-type-primary;
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
.u-slider__button {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ExtractPropTypes, PropType } from 'vue';
|
|
2
|
+
import { baseProps } from '../common/props';
|
|
3
|
+
import type { StepMode, ThemeType } from '../../types/global';
|
|
4
|
+
import { $u } from '../../';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* StepProps 步骤条 props 类型定义
|
|
8
|
+
* @description 步骤条,支持横向/竖向、主题色、激活色等
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export const StepProps = {
|
|
12
|
+
...baseProps,
|
|
13
|
+
/** 步骤条的类型,dot|number */
|
|
14
|
+
mode: { type: String as PropType<StepMode>, default: 'dot' },
|
|
15
|
+
/** 主题类型, primary|success|info|warning|error */
|
|
16
|
+
type: { type: String as PropType<ThemeType>, default: 'primary' },
|
|
17
|
+
/** 激活步骤的颜色 */
|
|
18
|
+
activeColor: { type: String, default: $u.color.primary },
|
|
19
|
+
/** 未激活的颜色 */
|
|
20
|
+
unActiveColor: { type: String, default: $u.color.info },
|
|
21
|
+
/** 自定义图标 */
|
|
22
|
+
icon: { type: String, default: 'checkmark' },
|
|
23
|
+
/** 标题 */
|
|
24
|
+
name: { type: String, default: '' },
|
|
25
|
+
/** 描述 */
|
|
26
|
+
desc: { type: String, default: '' }
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type StepProps = ExtractPropTypes<typeof StepProps>;
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="u-steps__item" :class="[customClass, 'u-steps__item--' + direction]" :style="$u.toStyle(customStyle)">
|
|
3
|
+
<view class="u-steps__item__num--wrap" v-if="mode == 'number'">
|
|
4
|
+
<view class="u-steps__item__num">
|
|
5
|
+
<view
|
|
6
|
+
class="u-steps__item__num--text"
|
|
7
|
+
v-if="currentIndex < childIndex"
|
|
8
|
+
:style="numberStyle(childIndex)"
|
|
9
|
+
>
|
|
10
|
+
<text :style="textStyle(childIndex)">
|
|
11
|
+
{{ childIndex + 1 }}
|
|
12
|
+
</text>
|
|
13
|
+
</view>
|
|
14
|
+
<view v-else class="u-steps__item__num--circle">
|
|
15
|
+
<slot name="icon">
|
|
16
|
+
<view class="u-steps__item__num--icon" :style="numberStyle(childIndex)">
|
|
17
|
+
<u-icon size="22" color="#ffffff" :name="iconName"></u-icon>
|
|
18
|
+
</view>
|
|
19
|
+
</slot>
|
|
20
|
+
</view>
|
|
21
|
+
</view>
|
|
22
|
+
</view>
|
|
23
|
+
<view class="u-steps__item__dot" v-else-if="mode == 'dot'">
|
|
24
|
+
<view class="u-steps__item__dot--box" :style="dotStyle(childIndex)"></view>
|
|
25
|
+
</view>
|
|
26
|
+
<view>
|
|
27
|
+
<view class="u-line-1" :style="textStyle(childIndex)" :class="['u-steps__item__text--' + direction]">
|
|
28
|
+
<slot name="name">
|
|
29
|
+
<text>
|
|
30
|
+
{{ name }}
|
|
31
|
+
</text>
|
|
32
|
+
</slot>
|
|
33
|
+
</view>
|
|
34
|
+
<view v-if="hasDesc" :class="['u-steps__item__desc--' + direction]">
|
|
35
|
+
<slot name="desc">
|
|
36
|
+
<text>
|
|
37
|
+
{{ desc }}
|
|
38
|
+
</text>
|
|
39
|
+
</slot>
|
|
40
|
+
</view>
|
|
41
|
+
</view>
|
|
42
|
+
<view class="u-steps__item__line" :class="['u-steps__item__line--' + mode]" v-if="showLine">
|
|
43
|
+
<u-line :direction="direction" length="100%" :hair-line="false" :color="unActiveColor"></u-line>
|
|
44
|
+
</view>
|
|
45
|
+
</view>
|
|
46
|
+
</template>
|
|
47
|
+
<script lang="ts">
|
|
48
|
+
export default {
|
|
49
|
+
name: 'u-step',
|
|
50
|
+
options: {
|
|
51
|
+
addGlobalClass: true,
|
|
52
|
+
// #ifndef MP-TOUTIAO
|
|
53
|
+
virtualHost: true,
|
|
54
|
+
// #endif
|
|
55
|
+
styleIsolation: 'shared'
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
</script>
|
|
59
|
+
<script setup lang="ts">
|
|
60
|
+
import { computed } from 'vue';
|
|
61
|
+
import { $u, useChildren } from '../..';
|
|
62
|
+
import { StepProps } from './types';
|
|
63
|
+
|
|
64
|
+
const props = defineProps(StepProps);
|
|
65
|
+
|
|
66
|
+
// 使用组件关系 hooks 获取父组件
|
|
67
|
+
const { childIndex, parentExposed } = useChildren('u-step', 'u-steps');
|
|
68
|
+
|
|
69
|
+
// 父组件的默认值(兼容没有父组件的场景)
|
|
70
|
+
const parentData = computed(() => {
|
|
71
|
+
return (
|
|
72
|
+
parentExposed?.value?.props || {
|
|
73
|
+
mode: 'dot',
|
|
74
|
+
list: [],
|
|
75
|
+
type: 'primary',
|
|
76
|
+
current: 0,
|
|
77
|
+
activeColor: $u.color.primary,
|
|
78
|
+
unActiveColor: $u.color.info,
|
|
79
|
+
icon: 'checkmark',
|
|
80
|
+
direction: 'row'
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const childLen = computed(() => {
|
|
86
|
+
if (parentExposed?.value?.childLen && typeof parentExposed?.value?.childLen === 'function') {
|
|
87
|
+
return parentExposed?.value?.childLen();
|
|
88
|
+
}
|
|
89
|
+
return 0;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const showLine = computed(() => childIndex.value < childLen.value - 1);
|
|
93
|
+
|
|
94
|
+
// 计算属性,计算当前步骤的索引值
|
|
95
|
+
// 如果 current 是字符串,则转换为数字,否则直接使用数字
|
|
96
|
+
const currentIndex = computed(() =>
|
|
97
|
+
typeof parentData.value.current === 'string' ? Number(parentData.value.current) : parentData.value.current
|
|
98
|
+
);
|
|
99
|
+
const mode = computed(() => parentData.value.mode);
|
|
100
|
+
const direction = computed(() => parentData.value.direction);
|
|
101
|
+
// 计算方向样式
|
|
102
|
+
|
|
103
|
+
const activeColor = computed(() => props.activeColor || parentData.value.activeColor);
|
|
104
|
+
const unActiveColor = computed(() => props.unActiveColor || parentData.value.unActiveColor);
|
|
105
|
+
|
|
106
|
+
const name = computed(() => props.name || '');
|
|
107
|
+
const desc = computed(() => props.desc || '');
|
|
108
|
+
const hasDesc = computed(() => !$u.test.isEmpty(desc));
|
|
109
|
+
const iconName = computed(() => {
|
|
110
|
+
if (props.icon !== parentData.value.icon) {
|
|
111
|
+
if (props.icon !== 'checkmark') {
|
|
112
|
+
return props.icon;
|
|
113
|
+
} else if (parentData.value.icon !== 'checkmark') {
|
|
114
|
+
return parentData.value.icon;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return props.icon || parentData.value.icon;
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// 计算当前步骤的样式
|
|
121
|
+
const numberStyle = (index: number) => ({
|
|
122
|
+
backgroundColor: currentIndex.value < index ? '#fff' : activeColor.value,
|
|
123
|
+
borderColor: currentIndex.value < index ? unActiveColor.value : activeColor.value
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// 计算当前步骤的样式
|
|
127
|
+
const dotStyle = (index: number) => ({
|
|
128
|
+
backgroundColor: index <= currentIndex.value ? activeColor.value : unActiveColor.value
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// 计算当前步骤的文字样式
|
|
132
|
+
const textStyle = (index: number) => ({
|
|
133
|
+
color: index <= currentIndex.value ? activeColor.value : unActiveColor.value
|
|
134
|
+
});
|
|
135
|
+
</script>
|
|
136
|
+
|
|
137
|
+
<style scoped lang="scss">
|
|
138
|
+
@import '../../libs/css/style.components.scss';
|
|
139
|
+
|
|
140
|
+
$u-steps-item-number-width: 44rpx;
|
|
141
|
+
$u-steps-item-dot-width: 20rpx;
|
|
142
|
+
|
|
143
|
+
.inline-block {
|
|
144
|
+
display: inline-block;
|
|
145
|
+
}
|
|
146
|
+
.u-steps__item {
|
|
147
|
+
flex: 1;
|
|
148
|
+
text-align: center;
|
|
149
|
+
position: relative;
|
|
150
|
+
min-width: 100rpx;
|
|
151
|
+
font-size: 26rpx;
|
|
152
|
+
color: #8799a3;
|
|
153
|
+
@include vue-flex;
|
|
154
|
+
flex-direction: column;
|
|
155
|
+
|
|
156
|
+
&--row {
|
|
157
|
+
align-items: center;
|
|
158
|
+
@include vue-flex;
|
|
159
|
+
flex-direction: column;
|
|
160
|
+
|
|
161
|
+
.u-steps__item__line {
|
|
162
|
+
position: absolute;
|
|
163
|
+
z-index: 0;
|
|
164
|
+
|
|
165
|
+
&--dot {
|
|
166
|
+
width: calc(100% - #{$u-steps-item-dot-width});
|
|
167
|
+
top: calc(#{$u-steps-item-dot-width} / 2);
|
|
168
|
+
left: calc(#{$u-steps-item-dot-width} / 2 + 50%);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
&--number {
|
|
172
|
+
width: calc(100% - $u-steps-item-number-width);
|
|
173
|
+
top: calc(#{$u-steps-item-number-width} / 2);
|
|
174
|
+
left: calc(#{$u-steps-item-number-width} / 2 + 50%);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
&--column {
|
|
180
|
+
@include vue-flex;
|
|
181
|
+
flex-direction: row;
|
|
182
|
+
justify-content: flex-start;
|
|
183
|
+
min-height: 120rpx;
|
|
184
|
+
padding-bottom: 6rpx;
|
|
185
|
+
|
|
186
|
+
.u-steps__item__line {
|
|
187
|
+
position: absolute;
|
|
188
|
+
z-index: 0;
|
|
189
|
+
|
|
190
|
+
&--dot {
|
|
191
|
+
height: calc(100% - #{$u-steps-item-dot-width});
|
|
192
|
+
top: calc(#{$u-steps-item-dot-width} + 6rpx);
|
|
193
|
+
left: calc(#{$u-steps-item-dot-width} / 2);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
&--number {
|
|
197
|
+
height: calc(100% - #{$u-steps-item-number-width});
|
|
198
|
+
top: #{$u-steps-item-number-width};
|
|
199
|
+
left: calc(#{$u-steps-item-number-width} / 2);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.u-steps__item__dot {
|
|
204
|
+
margin-top: 6rpx;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
&__num {
|
|
209
|
+
&--wrap {
|
|
210
|
+
width: $u-steps-item-number-width;
|
|
211
|
+
height: $u-steps-item-number-width;
|
|
212
|
+
}
|
|
213
|
+
&--text,
|
|
214
|
+
&--icon,
|
|
215
|
+
&--circle {
|
|
216
|
+
@include vue-flex;
|
|
217
|
+
align-items: center;
|
|
218
|
+
justify-content: center;
|
|
219
|
+
width: $u-steps-item-number-width;
|
|
220
|
+
height: $u-steps-item-number-width;
|
|
221
|
+
overflow: hidden;
|
|
222
|
+
}
|
|
223
|
+
&--text,
|
|
224
|
+
&--icon {
|
|
225
|
+
border: 1px solid #8799a3;
|
|
226
|
+
border-radius: 50%;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
&__dot {
|
|
231
|
+
display: inline-block;
|
|
232
|
+
width: $u-steps-item-dot-width;
|
|
233
|
+
height: $u-steps-item-dot-width;
|
|
234
|
+
// @include vue-flex;
|
|
235
|
+
&--box {
|
|
236
|
+
width: $u-steps-item-dot-width;
|
|
237
|
+
height: $u-steps-item-dot-width;
|
|
238
|
+
border-radius: 50%;
|
|
239
|
+
overflow: hidden;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
&__text--row {
|
|
244
|
+
margin-top: 14rpx;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
&__text--column {
|
|
248
|
+
margin-left: 14rpx;
|
|
249
|
+
text-align: left;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
&__desc--row {
|
|
253
|
+
color: $u-type-info;
|
|
254
|
+
font-size: 24rpx;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
&__desc--column {
|
|
258
|
+
margin-left: 14rpx;
|
|
259
|
+
text-align: left;
|
|
260
|
+
color: $u-type-info;
|
|
261
|
+
font-size: 24rpx;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
</style>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ExtractPropTypes, PropType } from 'vue';
|
|
2
2
|
import type { StepDirection, StepMode, StepsListItem, ThemeType } from '../../types/global';
|
|
3
3
|
import { baseProps } from '../common/props';
|
|
4
|
+
import { $u } from '../../';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* StepsProps 步骤条 props 类型定义
|
|
@@ -18,9 +19,9 @@ export const StepsProps = {
|
|
|
18
19
|
/** 当前哪一步是激活的 */
|
|
19
20
|
current: { type: [Number, String] as PropType<number | string>, default: 0 },
|
|
20
21
|
/** 激活步骤的颜色 */
|
|
21
|
-
activeColor: { type: String, default:
|
|
22
|
+
activeColor: { type: String, default: $u.color.primary },
|
|
22
23
|
/** 未激活的颜色 */
|
|
23
|
-
unActiveColor: { type: String, default:
|
|
24
|
+
unActiveColor: { type: String, default: $u.color.info },
|
|
24
25
|
/** 自定义图标 */
|
|
25
26
|
icon: { type: String, default: 'checkmark' },
|
|
26
27
|
/** step的排列方向,row-横向,column-竖向 */
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<view>
|
|
3
3
|
<view class="u-steps" :class="customClass" :style="$u.toStyle(directionStyle, customStyle)">
|
|
4
|
-
<
|
|
4
|
+
<slot>
|
|
5
|
+
<u-step
|
|
6
|
+
:name="item.name"
|
|
7
|
+
:desc="item.desc"
|
|
8
|
+
:icon="item.icon"
|
|
9
|
+
v-for="(item, index) in list"
|
|
10
|
+
:key="index"
|
|
11
|
+
></u-step>
|
|
12
|
+
</slot>
|
|
13
|
+
<!-- <view
|
|
5
14
|
class="u-steps__item"
|
|
6
15
|
:class="['u-steps__item--' + direction]"
|
|
7
16
|
v-for="(item, index) in list"
|
|
@@ -24,7 +33,7 @@
|
|
|
24
33
|
>
|
|
25
34
|
<u-line :direction="direction" length="100%" :hair-line="false" :color="unActiveColor"></u-line>
|
|
26
35
|
</view>
|
|
27
|
-
</view>
|
|
36
|
+
</view> -->
|
|
28
37
|
</view>
|
|
29
38
|
</view>
|
|
30
39
|
</template>
|
|
@@ -43,9 +52,9 @@ export default {
|
|
|
43
52
|
</script>
|
|
44
53
|
|
|
45
54
|
<script setup lang="ts">
|
|
46
|
-
import { computed } from 'vue';
|
|
55
|
+
import { computed, getCurrentInstance } from 'vue';
|
|
47
56
|
import { StepsProps } from './types';
|
|
48
|
-
import { $u } from '../..';
|
|
57
|
+
import { $u, useParent } from '../..';
|
|
49
58
|
|
|
50
59
|
/**
|
|
51
60
|
* steps 步骤条
|
|
@@ -64,118 +73,20 @@ import { $u } from '../..';
|
|
|
64
73
|
|
|
65
74
|
const props = defineProps(StepsProps);
|
|
66
75
|
|
|
67
|
-
|
|
68
|
-
// 如果 current 是字符串,则转换为数字,否则直接使用数字
|
|
69
|
-
const currentIndex = computed(() => (typeof props.current === 'string' ? Number(props.current) : props.current));
|
|
70
|
-
|
|
76
|
+
const { children } = useParent('u-steps');
|
|
71
77
|
// 计算方向样式
|
|
72
78
|
const directionStyle = computed(() => ({ flexDirection: props.direction as 'row' | 'column' }));
|
|
73
79
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
borderColor: currentIndex.value < index ? props.unActiveColor : props.activeColor
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// 计算当前步骤的样式
|
|
81
|
-
const dotStyle = (index: number) => ({
|
|
82
|
-
backgroundColor: index <= currentIndex.value ? props.activeColor : props.unActiveColor
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
// 计算当前步骤的文字样式
|
|
86
|
-
const textStyle = (index: number) => ({
|
|
87
|
-
color: index <= currentIndex.value ? props.activeColor : props.unActiveColor
|
|
80
|
+
defineExpose({
|
|
81
|
+
props,
|
|
82
|
+
childLen: () => children.length
|
|
88
83
|
});
|
|
89
84
|
</script>
|
|
90
85
|
|
|
91
86
|
<style lang="scss" scoped>
|
|
92
87
|
@import '../../libs/css/style.components.scss';
|
|
93
88
|
|
|
94
|
-
$u-steps-item-number-width: 44rpx;
|
|
95
|
-
$u-steps-item-dot-width: 20rpx;
|
|
96
|
-
|
|
97
89
|
.u-steps {
|
|
98
90
|
@include vue-flex;
|
|
99
|
-
|
|
100
|
-
.u-steps__item {
|
|
101
|
-
flex: 1;
|
|
102
|
-
text-align: center;
|
|
103
|
-
position: relative;
|
|
104
|
-
min-width: 100rpx;
|
|
105
|
-
font-size: 26rpx;
|
|
106
|
-
color: #8799a3;
|
|
107
|
-
@include vue-flex;
|
|
108
|
-
justify-content: center;
|
|
109
|
-
flex-direction: column;
|
|
110
|
-
align-items: center;
|
|
111
|
-
|
|
112
|
-
&--row {
|
|
113
|
-
@include vue-flex;
|
|
114
|
-
flex-direction: column;
|
|
115
|
-
|
|
116
|
-
.u-steps__item__line {
|
|
117
|
-
position: absolute;
|
|
118
|
-
z-index: 0;
|
|
119
|
-
left: 75%;
|
|
120
|
-
width: 50%;
|
|
121
|
-
|
|
122
|
-
&--dot {
|
|
123
|
-
top: calc(#{$u-steps-item-dot-width} / 2);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
&--number {
|
|
127
|
-
top: calc(#{$u-steps-item-number-width} / 2);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
&--column {
|
|
133
|
-
@include vue-flex;
|
|
134
|
-
flex-direction: row;
|
|
135
|
-
justify-content: flex-start;
|
|
136
|
-
min-height: 120rpx;
|
|
137
|
-
|
|
138
|
-
.u-steps__item__line {
|
|
139
|
-
position: absolute;
|
|
140
|
-
z-index: 0;
|
|
141
|
-
height: 50%;
|
|
142
|
-
top: 75%;
|
|
143
|
-
|
|
144
|
-
&--dot {
|
|
145
|
-
left: calc(#{$u-steps-item-dot-width} / 2);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
&--number {
|
|
149
|
-
left: calc(#{$u-steps-item-number-width} / 2);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
&__num {
|
|
155
|
-
@include vue-flex;
|
|
156
|
-
align-items: center;
|
|
157
|
-
justify-content: center;
|
|
158
|
-
width: $u-steps-item-number-width;
|
|
159
|
-
height: $u-steps-item-number-width;
|
|
160
|
-
border: 1px solid #8799a3;
|
|
161
|
-
border-radius: 50%;
|
|
162
|
-
overflow: hidden;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
&__dot {
|
|
166
|
-
width: $u-steps-item-dot-width;
|
|
167
|
-
height: $u-steps-item-dot-width;
|
|
168
|
-
@include vue-flex;
|
|
169
|
-
border-radius: 50%;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
&__text--row {
|
|
173
|
-
margin-top: 14rpx;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
&__text--column {
|
|
177
|
-
margin-left: 14rpx;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
91
|
}
|
|
181
92
|
</style>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ExtractPropTypes, PropType } from 'vue';
|
|
2
2
|
import { baseProps } from '../common/props';
|
|
3
|
+
import { $u } from '../../';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* SwitchProps 开关选择器 props 类型定义
|
|
@@ -14,7 +15,7 @@ export const SwitchProps = {
|
|
|
14
15
|
/** 开关尺寸,单位rpx */
|
|
15
16
|
size: { type: [Number, String] as PropType<number | string>, default: 50 },
|
|
16
17
|
/** 打开时的颜色 */
|
|
17
|
-
activeColor: { type: String, default:
|
|
18
|
+
activeColor: { type: String, default: $u.color.primary },
|
|
18
19
|
/** 关闭时的颜色 */
|
|
19
20
|
inactiveColor: { type: String, default: '#ffffff' },
|
|
20
21
|
/** v-model 绑定值,是否选中 */
|