stellar-ui-plus 1.24.26 → 1.25.0
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/ste-app-update/method.ts +1 -0
- package/components/ste-app-update/props.ts +11 -11
- package/components/ste-app-update/ste-app-update.vue +2 -7
- package/components/ste-radio/README.md +1 -1
- package/components/ste-radio/ste-radio.vue +2 -7
- package/components/ste-radio-group/ste-radio-group.vue +2 -1
- package/components/ste-select-seat/ATTRIBUTES.md +18 -0
- package/components/ste-select-seat/README.md +280 -0
- package/components/ste-select-seat/canvasUtils.ts +42 -0
- package/components/ste-select-seat/config.json +5 -0
- package/components/ste-select-seat/internals/gridUtils.ts +23 -0
- package/components/ste-select-seat/internals/seatLayout.ts +169 -0
- package/components/ste-select-seat/internals/useSeatInteraction.ts +540 -0
- package/components/ste-select-seat/props.ts +37 -0
- package/components/ste-select-seat/ste-select-seat.easycom.json +62 -0
- package/components/ste-select-seat/ste-select-seat.vue +517 -0
- package/components/ste-select-seat/types.d.ts +33 -0
- package/components/ste-select-seat/useData.ts +179 -0
- package/components/ste-select-seat/useTouchCompat.ts +89 -0
- package/components/ste-simple-calendar/ATTRIBUTES.md +17 -0
- package/components/ste-simple-calendar/README.md +112 -0
- package/components/ste-simple-calendar/config.json +5 -0
- package/components/ste-simple-calendar/props.ts +32 -0
- package/components/ste-simple-calendar/ste-simple-calendar.easycom.json +60 -0
- package/components/ste-simple-calendar/ste-simple-calendar.vue +265 -0
- package/components/ste-simple-calendar/type.d.ts +30 -0
- package/components/ste-simple-calendar/useData.ts +60 -0
- package/components/ste-skeleton/ATTRIBUTES.md +7 -0
- package/components/ste-skeleton/README.md +82 -0
- package/components/ste-skeleton/config.json +5 -0
- package/components/ste-skeleton/props.ts +7 -0
- package/components/ste-skeleton/ste-skeleton.easycom.json +38 -0
- package/components/ste-skeleton/ste-skeleton.vue +90 -0
- package/components/ste-slide-verify/ATTRIBUTES.md +27 -0
- package/components/ste-slide-verify/README.md +118 -0
- package/components/ste-slide-verify/config.json +5 -0
- package/components/ste-slide-verify/props.ts +43 -0
- package/components/ste-slide-verify/ste-slide-verify.easycom.json +119 -0
- package/components/ste-slide-verify/ste-slide-verify.vue +535 -0
- package/index.ts +8 -0
- package/package.json +1 -1
- package/types/components.d.ts +8 -0
- package/types/index.d.ts +2 -0
- package/types/refComponents.d.ts +8 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, ref } from 'vue';
|
|
3
|
+
import utils from '../../utils/utils';
|
|
4
|
+
import propsData from './props';
|
|
5
|
+
import { useSimpleCalendar } from './useData';
|
|
6
|
+
import type { SimpleCalendarEmits, SimpleCalendarExpose } from './type.d';
|
|
7
|
+
|
|
8
|
+
const componentName = 'ste-simple-calendar';
|
|
9
|
+
|
|
10
|
+
defineOptions({
|
|
11
|
+
name: componentName,
|
|
12
|
+
options: {
|
|
13
|
+
virtualHost: true,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const props = defineProps(propsData);
|
|
18
|
+
|
|
19
|
+
const emit = defineEmits<SimpleCalendarEmits>();
|
|
20
|
+
|
|
21
|
+
const { dateInfo, formattedMonth, setDate, getDateInfo, today } = useSimpleCalendar(props, emit);
|
|
22
|
+
|
|
23
|
+
// 获取安全区域信息
|
|
24
|
+
const { safeArea } = utils.System.getWindowInfo();
|
|
25
|
+
|
|
26
|
+
// 控制日历弹窗显示
|
|
27
|
+
const showPopup = ref(false);
|
|
28
|
+
|
|
29
|
+
// 日历选中的日期列表
|
|
30
|
+
const calendarList = computed(() => {
|
|
31
|
+
return [pendingSelectedDate.value];
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// 日历默认日期(格式化为时间戳)
|
|
35
|
+
const calendarDefaultDate = computed(() => {
|
|
36
|
+
return utils.dayjs(pendingSelectedDate.value).valueOf();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// 弹窗中待确认的日期
|
|
40
|
+
const pendingSelectedDate = ref<string | number>(dateInfo.value.date);
|
|
41
|
+
|
|
42
|
+
// 根节点样式
|
|
43
|
+
const rootStyle = computed(() => {
|
|
44
|
+
return {
|
|
45
|
+
...props.customStyle,
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// 日期数字样式
|
|
50
|
+
const dayStyle = computed(() => {
|
|
51
|
+
return {
|
|
52
|
+
color: props.color,
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// 星期文本样式
|
|
57
|
+
const weekStyle = computed(() => {
|
|
58
|
+
return {
|
|
59
|
+
color: props.color,
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// 年月文本样式
|
|
64
|
+
const monthStyle = computed(() => {
|
|
65
|
+
return {
|
|
66
|
+
color: props.color,
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// 底部按钮区域样式(包含安全距离)
|
|
71
|
+
const actionBoxStyle = computed(() => {
|
|
72
|
+
const bottomSafeArea = safeArea.bottom || 0;
|
|
73
|
+
const screenHeight = utils.System.getWindowInfo().screenHeight || 0;
|
|
74
|
+
const safeAreaInsetBottom = screenHeight - bottomSafeArea;
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
paddingBottom: `calc(20rpx + ${safeAreaInsetBottom}px)`,
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// 点击组件
|
|
82
|
+
const handleClick = () => {
|
|
83
|
+
emit('click', dateInfo.value);
|
|
84
|
+
if (props.showCalendar) {
|
|
85
|
+
pendingSelectedDate.value = dateInfo.value.date;
|
|
86
|
+
showPopup.value = true;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// 重置日历
|
|
91
|
+
const handleReset = () => {
|
|
92
|
+
setDate(Date.now());
|
|
93
|
+
pendingSelectedDate.value = utils.dayjs().format('YYYY-MM-DD');
|
|
94
|
+
showPopup.value = false;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// 日历选择日期
|
|
98
|
+
const handleCalendarSelect = (days: (string | number)[], day: string | number) => {
|
|
99
|
+
pendingSelectedDate.value = day || days?.[0] || pendingSelectedDate.value;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// 日历确认选择
|
|
103
|
+
const handleCalendarConfirm = () => {
|
|
104
|
+
setDate(pendingSelectedDate.value);
|
|
105
|
+
showPopup.value = false;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// 暴露方法
|
|
109
|
+
defineExpose<SimpleCalendarExpose>({
|
|
110
|
+
setDate,
|
|
111
|
+
getDateInfo,
|
|
112
|
+
today,
|
|
113
|
+
});
|
|
114
|
+
</script>
|
|
115
|
+
|
|
116
|
+
<template>
|
|
117
|
+
<view :class="['ste-simple-calendar', customClass]" :style="rootStyle" @click="handleClick">
|
|
118
|
+
<!-- 日期数字 -->
|
|
119
|
+
<view class="ste-simple-calendar__day-box">
|
|
120
|
+
<text class="ste-simple-calendar__day" :style="dayStyle">{{ dateInfo.day }}</text>
|
|
121
|
+
</view>
|
|
122
|
+
|
|
123
|
+
<!-- 星期标签 -->
|
|
124
|
+
<view class="ste-simple-calendar__week-box">
|
|
125
|
+
<text v-for="(char, index) in dateInfo.weekText" :key="index" class="ste-simple-calendar__week-text" :style="weekStyle">
|
|
126
|
+
{{ char }}
|
|
127
|
+
</text>
|
|
128
|
+
</view>
|
|
129
|
+
|
|
130
|
+
<!-- 年月文本 -->
|
|
131
|
+
<view class="ste-simple-calendar__month-box">
|
|
132
|
+
<text class="ste-simple-calendar__month" :style="monthStyle">
|
|
133
|
+
{{ formattedMonth }}
|
|
134
|
+
</text>
|
|
135
|
+
</view>
|
|
136
|
+
</view>
|
|
137
|
+
|
|
138
|
+
<!-- 日历弹窗 -->
|
|
139
|
+
<ste-popup v-model:show="showPopup" height="60vh" position="bottom" :showClose="false">
|
|
140
|
+
<view class="calendar-popup">
|
|
141
|
+
<view class="calendar-wrapper">
|
|
142
|
+
<ste-calendar :list="calendarList" :defaultDate="calendarDefaultDate" :showConfirm="false" :show-title="false" @select="handleCalendarSelect" />
|
|
143
|
+
</view>
|
|
144
|
+
<view class="action-box" :style="actionBoxStyle">
|
|
145
|
+
<view class="btn reset" @click="handleReset">
|
|
146
|
+
<text class="btn-text">重置</text>
|
|
147
|
+
</view>
|
|
148
|
+
<view class="btn confirm" @click="handleCalendarConfirm">
|
|
149
|
+
<text class="btn-text">确认</text>
|
|
150
|
+
</view>
|
|
151
|
+
</view>
|
|
152
|
+
</view>
|
|
153
|
+
</ste-popup>
|
|
154
|
+
</template>
|
|
155
|
+
|
|
156
|
+
<style lang="scss" scoped>
|
|
157
|
+
.ste-simple-calendar {
|
|
158
|
+
display: flex;
|
|
159
|
+
flex-direction: row;
|
|
160
|
+
align-items: center;
|
|
161
|
+
box-sizing: border-box;
|
|
162
|
+
height: 45rpx;
|
|
163
|
+
|
|
164
|
+
&__day-box {
|
|
165
|
+
background-color: var(--simple-calendar-day-bg, #f3f3f3);
|
|
166
|
+
border-radius: 2rpx;
|
|
167
|
+
padding: 0 10rpx;
|
|
168
|
+
display: flex;
|
|
169
|
+
align-items: center;
|
|
170
|
+
justify-content: center;
|
|
171
|
+
height: 100%;
|
|
172
|
+
margin-right: 6rpx;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
&__day {
|
|
176
|
+
font-size: var(--simple-calendar-day-font-size, 32rpx);
|
|
177
|
+
font-weight: bold;
|
|
178
|
+
color: var(--simple-calendar-day-color, #000000);
|
|
179
|
+
line-height: 1;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
&__week-box {
|
|
183
|
+
background-color: var(--simple-calendar-week-bg, #f3f3f3);
|
|
184
|
+
border-radius: 2rpx;
|
|
185
|
+
padding: 0 10rpx;
|
|
186
|
+
display: flex;
|
|
187
|
+
flex-direction: column;
|
|
188
|
+
align-items: center;
|
|
189
|
+
justify-content: center;
|
|
190
|
+
height: 100%;
|
|
191
|
+
margin-right: 6rpx;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
&__week-text {
|
|
195
|
+
font-size: var(--simple-calendar-week-font-size, 16rpx);
|
|
196
|
+
color: var(--simple-calendar-week-color, #333333);
|
|
197
|
+
line-height: 1.1;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
&__month-box {
|
|
201
|
+
background-color: var(--simple-calendar-month-bg, #f3f3f3);
|
|
202
|
+
border-radius: 2rpx;
|
|
203
|
+
padding: 0 16rpx;
|
|
204
|
+
display: flex;
|
|
205
|
+
align-items: center;
|
|
206
|
+
justify-content: center;
|
|
207
|
+
height: 100%;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
&__month {
|
|
211
|
+
font-size: var(--simple-calendar-month-font-size, 24rpx);
|
|
212
|
+
color: var(--simple-calendar-month-color, #333333);
|
|
213
|
+
line-height: 1;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.calendar-popup {
|
|
218
|
+
display: flex;
|
|
219
|
+
flex-direction: column;
|
|
220
|
+
height: 100%;
|
|
221
|
+
overflow: hidden;
|
|
222
|
+
|
|
223
|
+
.calendar-wrapper {
|
|
224
|
+
flex: 1;
|
|
225
|
+
overflow: hidden;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.action-box {
|
|
229
|
+
flex-shrink: 0;
|
|
230
|
+
display: flex;
|
|
231
|
+
padding: 20rpx 32rpx;
|
|
232
|
+
background-color: #fff;
|
|
233
|
+
border-top: 1rpx solid #f0f0f0;
|
|
234
|
+
|
|
235
|
+
.btn {
|
|
236
|
+
flex: 1;
|
|
237
|
+
height: 80rpx;
|
|
238
|
+
display: flex;
|
|
239
|
+
align-items: center;
|
|
240
|
+
justify-content: center;
|
|
241
|
+
border-radius: 8rpx;
|
|
242
|
+
cursor: pointer;
|
|
243
|
+
|
|
244
|
+
&.reset {
|
|
245
|
+
background-color: #f5f5f5;
|
|
246
|
+
margin-right: 20rpx;
|
|
247
|
+
|
|
248
|
+
.btn-text {
|
|
249
|
+
color: #666;
|
|
250
|
+
font-size: 28rpx;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
&.confirm {
|
|
255
|
+
background-color: var(--ste-theme-color, #0090ff);
|
|
256
|
+
|
|
257
|
+
.btn-text {
|
|
258
|
+
color: #fff;
|
|
259
|
+
font-size: 28rpx;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
</style>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** 日期信息对象 */
|
|
2
|
+
export interface DateInfo {
|
|
3
|
+
/** 完整日期字符串,格式为 YYYY-MM-DD */
|
|
4
|
+
date: string;
|
|
5
|
+
/** 年份 */
|
|
6
|
+
year: number;
|
|
7
|
+
/** 月份,1-12 */
|
|
8
|
+
month: number;
|
|
9
|
+
/** 日期,1-31 */
|
|
10
|
+
day: number;
|
|
11
|
+
/** 星期几,0-6(0=周日) */
|
|
12
|
+
weekday: number;
|
|
13
|
+
/** 星期文本 */
|
|
14
|
+
weekText: string;
|
|
15
|
+
/** 时间戳 */
|
|
16
|
+
timestamp: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** 组件 Emits 类型定义 */
|
|
20
|
+
export interface SimpleCalendarEmits {
|
|
21
|
+
(e: 'click', dateInfo: DateInfo): void;
|
|
22
|
+
(e: 'date-change', dateInfo: DateInfo): void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** 组件暴露的方法 */
|
|
26
|
+
export interface SimpleCalendarExpose {
|
|
27
|
+
setDate: (date: string | number | Date) => void;
|
|
28
|
+
getDateInfo: () => DateInfo;
|
|
29
|
+
today: () => void;
|
|
30
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { computed, ref, watch } from 'vue';
|
|
2
|
+
import utils from '../../utils/utils';
|
|
3
|
+
import type { DateInfo } from './type.d';
|
|
4
|
+
|
|
5
|
+
export const useSimpleCalendar = (props: any, emit: any) => {
|
|
6
|
+
const currentDate = ref<any>(props.date);
|
|
7
|
+
|
|
8
|
+
// 计算日期信息
|
|
9
|
+
const dateInfo = computed<DateInfo>(() => {
|
|
10
|
+
const d = utils.dayjs(currentDate.value);
|
|
11
|
+
return {
|
|
12
|
+
date: d.format('YYYY-MM-DD'),
|
|
13
|
+
year: d.year(),
|
|
14
|
+
month: d.month() + 1,
|
|
15
|
+
day: d.date(),
|
|
16
|
+
weekday: d.day(),
|
|
17
|
+
weekText: props.weekTexts[d.day()],
|
|
18
|
+
timestamp: d.valueOf(),
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// 格式化年月
|
|
23
|
+
const formattedMonth = computed(() => {
|
|
24
|
+
return utils.dayjs(currentDate.value).format(props.formatter);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// 监听 date 属性变化
|
|
28
|
+
watch(
|
|
29
|
+
() => props.date,
|
|
30
|
+
(newVal) => {
|
|
31
|
+
currentDate.value = newVal;
|
|
32
|
+
emit('date-change', dateInfo.value);
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// 设置日期
|
|
37
|
+
const setDate = (date: string | number | Date) => {
|
|
38
|
+
currentDate.value = date;
|
|
39
|
+
emit('date-change', dateInfo.value);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// 获取日期信息
|
|
43
|
+
const getDateInfo = (): DateInfo => {
|
|
44
|
+
return dateInfo.value;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// 回到今天
|
|
48
|
+
const today = () => {
|
|
49
|
+
currentDate.value = Date.now();
|
|
50
|
+
emit('date-change', dateInfo.value);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
dateInfo,
|
|
55
|
+
formattedMonth,
|
|
56
|
+
setDate,
|
|
57
|
+
getDateInfo,
|
|
58
|
+
today,
|
|
59
|
+
};
|
|
60
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
#### Props
|
|
2
|
+
| 属性名 | 说明 | 类型 | 默认值 | 可选值 | 支持版本 |
|
|
3
|
+
| ----- | ----- | --- | ------- | ------ | -------- |
|
|
4
|
+
| `loading` | 是否显示骨架图 | `boolean` | `true` | - | - |
|
|
5
|
+
| `type` | 骨架图类型 | `string` | `text` | `text`:文本<br/>`image`:图片<br/>`circle`:圆形<br/>`button`:按钮 | - |
|
|
6
|
+
|
|
7
|
+
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Skeleton 骨架图
|
|
2
|
+
|
|
3
|
+
骨架图组件用于在数据加载过程中显示页面的基本结构,避免页面的突然变化,为用户提供更好的视觉体验。组件支持多种预设类型,也可以通过组合使用来构建复杂的骨架结构。
|
|
4
|
+
|
|
5
|
+
---$
|
|
6
|
+
|
|
7
|
+
### 代码演示
|
|
8
|
+
|
|
9
|
+
JavaScript后面的演示代码中涉及到的变量和方法都使用本`javascript`代码
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
import { ref, onMounted } from 'vue';
|
|
13
|
+
const loading = ref(true);
|
|
14
|
+
|
|
15
|
+
onMounted(() => {
|
|
16
|
+
setTimeout(() => {
|
|
17
|
+
loading.value = false;
|
|
18
|
+
}, 3000);
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
#### 骨架类型
|
|
23
|
+
|
|
24
|
+
通过`type`属性,设置骨架图类型
|
|
25
|
+
|
|
26
|
+
##### 基础文本骨架
|
|
27
|
+
|
|
28
|
+
最简单的文本内容骨架图用法
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<template>
|
|
32
|
+
<!-- 显示骨架图 -->
|
|
33
|
+
<ste-skeleton :loading="loading">
|
|
34
|
+
<ste-text>床前明月光,疑是地上霜。</ste-text>
|
|
35
|
+
</ste-skeleton>
|
|
36
|
+
|
|
37
|
+
<!-- 隐藏骨架图,显示真实内容 -->
|
|
38
|
+
<ste-skeleton :loading="false">
|
|
39
|
+
<ste-text>床前明月光,疑是地上霜。</ste-text>
|
|
40
|
+
</ste-skeleton>
|
|
41
|
+
</template>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
##### 图片骨架
|
|
45
|
+
|
|
46
|
+
适用于矩形图片的骨架展示:
|
|
47
|
+
|
|
48
|
+
```html
|
|
49
|
+
<template>
|
|
50
|
+
<ste-skeleton :loading="loading" type="image">
|
|
51
|
+
<ste-image src="https://image.whzb.com/chain/StellarUI/图片.jpg" width="120" height="120" />
|
|
52
|
+
</ste-skeleton>
|
|
53
|
+
</template>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
##### 圆形头像骨架
|
|
57
|
+
|
|
58
|
+
适用于圆形头像或图标的骨架展示:
|
|
59
|
+
|
|
60
|
+
```html
|
|
61
|
+
<template>
|
|
62
|
+
<ste-skeleton :loading="loading" type="circle">
|
|
63
|
+
<ste-image src="https://image.whzb.com/chain/StellarUI/图片.jpg" width="120" height="120" radius="50" />
|
|
64
|
+
</ste-skeleton>
|
|
65
|
+
</template>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---$
|
|
69
|
+
|
|
70
|
+
### API
|
|
71
|
+
|
|
72
|
+
<!-- props -->
|
|
73
|
+
|
|
74
|
+
#### 组件插槽(Slots)
|
|
75
|
+
|
|
76
|
+
| 名称 | 说明 | 支持版本 |
|
|
77
|
+
| ------- | -------- | -------- |
|
|
78
|
+
| default | 默认插槽 | - |
|
|
79
|
+
|
|
80
|
+
---$
|
|
81
|
+
|
|
82
|
+
{{qinpengfei}}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ste-skeleton",
|
|
3
|
+
"description": "骨架屏组件",
|
|
4
|
+
"example": "<ste-skeleton></ste-skeleton>",
|
|
5
|
+
"tutorial": "https://stellar-ui.intecloud.com.cn/?projectName=stellar-ui-plus&menu=%E7%BB%84%E4%BB%B6&active=ste-skeleton",
|
|
6
|
+
"attributes": [
|
|
7
|
+
{
|
|
8
|
+
"name": "loading",
|
|
9
|
+
"description": "是否显示骨架图",
|
|
10
|
+
"type": "boolean",
|
|
11
|
+
"default": true
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "type",
|
|
15
|
+
"description": "骨架图类型",
|
|
16
|
+
"type": "string",
|
|
17
|
+
"values": [
|
|
18
|
+
{
|
|
19
|
+
"name": "text",
|
|
20
|
+
"description": "文本"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "image",
|
|
24
|
+
"description": "图片"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "circle",
|
|
28
|
+
"description": "圆形"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "button",
|
|
32
|
+
"description": "按钮"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"default": "text"
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view
|
|
3
|
+
class="ste-skeleton"
|
|
4
|
+
:class="[
|
|
5
|
+
{
|
|
6
|
+
'ste-skeleton--loading': loading,
|
|
7
|
+
},
|
|
8
|
+
`ste-skeleton--${type}`,
|
|
9
|
+
]"
|
|
10
|
+
>
|
|
11
|
+
<template v-if="loading">
|
|
12
|
+
<ste-icon v-if="type == 'image'" :size="20" code=""></ste-icon>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<template v-else>
|
|
16
|
+
<slot></slot>
|
|
17
|
+
</template>
|
|
18
|
+
</view>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script setup lang="ts">
|
|
22
|
+
import propsData from './props';
|
|
23
|
+
const componentName = `ste-skeleton`;
|
|
24
|
+
|
|
25
|
+
defineOptions({
|
|
26
|
+
name: componentName,
|
|
27
|
+
});
|
|
28
|
+
const props = defineProps(propsData);
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<style lang="scss" scoped>
|
|
32
|
+
.ste-skeleton {
|
|
33
|
+
&.ste-skeleton--loading {
|
|
34
|
+
background-color: #fafafb;
|
|
35
|
+
border-radius: 8rpx;
|
|
36
|
+
|
|
37
|
+
&.ste-skeleton--text {
|
|
38
|
+
height: 32rpx;
|
|
39
|
+
width: 300rpx;
|
|
40
|
+
border-radius: 8rpx;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&.ste-skeleton--image {
|
|
44
|
+
display: flex;
|
|
45
|
+
align-items: center;
|
|
46
|
+
justify-content: center;
|
|
47
|
+
flex-direction: row;
|
|
48
|
+
width: 120rpx;
|
|
49
|
+
height: 120rpx;
|
|
50
|
+
border-radius: 16rpx;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
&.ste-skeleton--circle {
|
|
54
|
+
border-radius: 50%;
|
|
55
|
+
width: 120rpx;
|
|
56
|
+
height: 120rpx;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&.ste-skeleton--button {
|
|
60
|
+
border-radius: 16rpx;
|
|
61
|
+
height: 64rpx;
|
|
62
|
+
width: 176rpx;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* 定义骨架屏闪烁动画 */
|
|
68
|
+
@keyframes skeleton-blink {
|
|
69
|
+
0% {
|
|
70
|
+
opacity: 0.3;
|
|
71
|
+
}
|
|
72
|
+
100% {
|
|
73
|
+
opacity: 1;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* 骨架屏基础样式与动画绑定 */
|
|
78
|
+
.ste-skeleton--loading {
|
|
79
|
+
/* 对应 duration: 2000ms */
|
|
80
|
+
animation-duration: 2s;
|
|
81
|
+
/* 对应 loop: -1 (无限循环) */
|
|
82
|
+
animation-iteration-count: infinite;
|
|
83
|
+
/* 对应 alternate: true (交替方向) */
|
|
84
|
+
animation-direction: alternate;
|
|
85
|
+
/* 动画名称 */
|
|
86
|
+
animation-name: skeleton-blink;
|
|
87
|
+
/* 保证动画平滑过渡 */
|
|
88
|
+
animation-timing-function: ease-in-out;
|
|
89
|
+
}
|
|
90
|
+
</style>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#### Props
|
|
2
|
+
| 属性名 | 说明 | 类型 | 默认值 | 可选值 | 支持版本 |
|
|
3
|
+
| ----- | ----- | --- | ------- | ------ | -------- |
|
|
4
|
+
| `modelValue` | 验证状态(支持 v-model 双向绑定) | `Boolean` | `false` | - | - |
|
|
5
|
+
| `mode` | 验证模式,可选值为 slide / image | `String` | `slide` | - | - |
|
|
6
|
+
| `size` | 轨道高度和滑块大小,默认单位 rpx | `Number/String` | `40` | - | - |
|
|
7
|
+
| `disabled` | 是否禁用 | `Boolean` | `false` | - | - |
|
|
8
|
+
| `imageUrl` | 图片旋转模式下的图片地址 | `String` | `` | - | - |
|
|
9
|
+
| `imageSize` | 图片旋转模式下的图片尺寸,默认单位 rpx | `Number/String` | `150` | - | - |
|
|
10
|
+
| `angleThreshold` | 图片旋转验证的角度容差 | `Number` | `10` | - | - |
|
|
11
|
+
| `text` | 默认提示文案 | `String` | `` | - | - |
|
|
12
|
+
| `successText` | 验证成功文案 | `String` | `验证成功` | - | - |
|
|
13
|
+
| `showFail` | 失败时是否显示失败态 | `Boolean` | `true` | - | - |
|
|
14
|
+
| `failText` | 失败提示文案 | `String` | `验证失败` | - | - |
|
|
15
|
+
| `failDuration` | 失败态停留时长,单位 ms | `Number` | `800` | - | - |
|
|
16
|
+
| `activeColor` | 拖动过程中的激活颜色 | `String` | `#0090FF` | - | - |
|
|
17
|
+
| `inactiveColor` | 未激活背景色 | `String` | `#f3f4f6` | - | - |
|
|
18
|
+
| `successColor` | 成功态颜色 | `String` | `#13ce66` | - | - |
|
|
19
|
+
| `failColor` | 失败态颜色 | `String` | `#ee0a24` | - | - |
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
#### Events
|
|
23
|
+
| 事件名 | 说明 | 事件参数 | 支持版本 |
|
|
24
|
+
| ----- | ----- | ------- | -------- |
|
|
25
|
+
| `change` | 拖动过程中实时触发 | - | - |
|
|
26
|
+
| `success` | 验证成功时触发 | - | - |
|
|
27
|
+
| `fail` | 验证失败时触发 | - | - |
|