v-uni-app-ui 1.0.2 → 1.0.6

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.
Files changed (65) hide show
  1. package/README.md +127 -0
  2. package/dist/v-uni-app-ui.css +1 -0
  3. package/dist/v-uni-app-ui.es.js +6569 -0
  4. package/dist/v-uni-app-ui.umd.js +7 -0
  5. package/package.json +28 -8
  6. package/components/config.js +0 -123
  7. package/components/layout/v-card/v-card.vue +0 -108
  8. package/components/layout/v-grid/v-grid.vue +0 -162
  9. package/components/layout/v-icon-grid/v-icon-grid.vue +0 -195
  10. package/components/layout/v-infinite-scroll/v-infinite-scroll.vue +0 -172
  11. package/components/layout/v-list/v-list.vue +0 -43
  12. package/components/layout/v-row/v-row.vue +0 -142
  13. package/components/layout/v-waterfall/v-waterfall.vue +0 -79
  14. package/components/model/compound/v-checkbox-group/v-checkbox-group.vue +0 -96
  15. package/components/model/compound/v-console/v-console.js +0 -20
  16. package/components/model/compound/v-console/v-console.vue +0 -299
  17. package/components/model/compound/v-date-time/v-date-time.vue +0 -261
  18. package/components/model/compound/v-dialog/v-dialog.vue +0 -178
  19. package/components/model/compound/v-drum-select-picker/v-drum-select-picker.vue +0 -83
  20. package/components/model/compound/v-form/v-form.vue +0 -226
  21. package/components/model/compound/v-form-item/v-form-item.vue +0 -255
  22. package/components/model/compound/v-image/v-image.vue +0 -357
  23. package/components/model/compound/v-input-desensitize/v-input-desensitize.vue +0 -101
  24. package/components/model/compound/v-page/v-page.vue +0 -11
  25. package/components/model/compound/v-pages/v-pages.vue +0 -141
  26. package/components/model/compound/v-picker-list/v-picker-list.vue +0 -109
  27. package/components/model/compound/v-popup/v-popup.vue +0 -151
  28. package/components/model/compound/v-radio-group/v-radio-group.vue +0 -86
  29. package/components/model/compound/v-select-picker/v-select-picker.vue +0 -202
  30. package/components/model/compound/v-series-picker-list/v-series-picker-list.vue +0 -221
  31. package/components/model/compound/v-series-select-picker/v-series-select-picker.vue +0 -203
  32. package/components/model/compound/v-switch/v-switch.vue +0 -136
  33. package/components/model/compound/v-tabs-page/v-tabs-page.vue +0 -138
  34. package/components/model/native/v-badge/v-badge.vue +0 -143
  35. package/components/model/native/v-button/v-button.vue +0 -273
  36. package/components/model/native/v-carousel/v-carousel.vue +0 -138
  37. package/components/model/native/v-checkbox/v-checkbox.vue +0 -215
  38. package/components/model/native/v-collapse/v-collapse.vue +0 -190
  39. package/components/model/native/v-header-navigation-bar/v-header-navigation-bar.vue +0 -92
  40. package/components/model/native/v-input/v-input.vue +0 -352
  41. package/components/model/native/v-input-code/v-input-code.vue +0 -146
  42. package/components/model/native/v-loading/v-loading.vue +0 -206
  43. package/components/model/native/v-menu/v-menu.vue +0 -222
  44. package/components/model/native/v-menu-slide/v-menu-slide.vue +0 -364
  45. package/components/model/native/v-min-loading/v-min-loading.vue +0 -80
  46. package/components/model/native/v-null/v-null.vue +0 -97
  47. package/components/model/native/v-overlay/v-overlay.vue +0 -96
  48. package/components/model/native/v-pull-up-refresh/v-pull-up-refresh.vue +0 -157
  49. package/components/model/native/v-radio/v-radio.vue +0 -138
  50. package/components/model/native/v-scroll-list/v-scroll-list.vue +0 -169
  51. package/components/model/native/v-steps/v-steps.vue +0 -253
  52. package/components/model/native/v-table/v-table.vue +0 -203
  53. package/components/model/native/v-tabs/v-tabs.vue +0 -235
  54. package/components/model/native/v-tag/v-tag.vue +0 -206
  55. package/components/model/native/v-text/v-text.vue +0 -187
  56. package/components/model/native/v-text-button/v-text-button.vue +0 -139
  57. package/components/model/native/v-textarea/v-textarea.vue +0 -178
  58. package/components/model/native/v-title/v-title.vue +0 -91
  59. package/components/model/native/v-toast/info.png +0 -0
  60. package/components/model/native/v-toast/success.png +0 -0
  61. package/components/model/native/v-toast/v-toast.vue +0 -198
  62. package/components/model/native/v-toast/warn.png +0 -0
  63. package/components/model/native/v-upload-file-button/v-upload-file-button.vue +0 -296
  64. package/components/model/native/v-video/v-video.vue +0 -175
  65. package/components/model/native/v-window/v-window.vue +0 -158
@@ -1,273 +0,0 @@
1
- <template>
2
- <button
3
- :class="['v-button', `v-button--${size} v-button--${type} v-button--${model}`, { 'v-button--loading': loading, 'v-button--disabled': disabled, 'v-button--plain': plain }]"
4
- :disabled="disabled || loading"
5
- @click="handleClick"
6
- >
7
- <view v-if="loading" class="spinner"></view>
8
- <slot v-else></slot>
9
- </button>
10
- </template>
11
-
12
- <script setup lang="ts">
13
- import { ref, onUnmounted, inject } from 'vue';
14
- /**
15
- * v-button 按钮
16
- * type 按钮类型 默认值:default 可选值default默认、delete删除、succeed成功、info信息、warn警告
17
- * size 按钮大小 默认值:medium 可选值small小、medium中、large大
18
- * model 按钮模式 默认值:semicircle圆角按钮 可选值:square方形按钮、circle圆形按钮、border下边框按钮、text文本
19
- * disabled 是否禁用 true禁用 false不禁用
20
- * loading 是否加载 true加载 false不加载
21
- * plain 是否镂空 默认值:false 可选值:true镂空 false不镂空
22
- * stabilizationTime 防抖时间 默认值0
23
- * intervalUpdateTime 间隔触发防抖时间
24
- * degressionTime 递减时间
25
- */
26
- const props = defineProps({
27
- type: {
28
- type: String,
29
- default: 'default'
30
- },
31
- model: {
32
- type: String,
33
- default: 'semicircle',
34
- validator: (v: string) => ['semicircle', 'square', 'circle', 'border'].includes(v)
35
- },
36
- size: {
37
- type: String,
38
- default: 'medium',
39
- validator: (value: string) => ['small', 'medium', 'large'].includes(value)
40
- },
41
- disabled: {
42
- type: Boolean,
43
- default: false
44
- },
45
- loading: {
46
- type: Boolean,
47
- default: false
48
- },
49
- plain: {
50
- type: Boolean,
51
- default: false
52
- },
53
- stabilizationTime: {
54
- type: Number,
55
- default: 0
56
- },
57
- intervalUpdateTime: {
58
- type: Number,
59
- default: 1000
60
- },
61
- degressionTime: {
62
- type: Number,
63
- default: 1000
64
- }
65
- });
66
-
67
- const emit = defineEmits(['click', 'countdown']);
68
-
69
- const config = inject<any>('config');
70
- const clickTimer = ref<number | null>(null);
71
- const countdownTimer = ref<number | null>(null);
72
- const countdown = ref<number>(props.stabilizationTime);
73
- const isCountingDown = ref(false);
74
-
75
- onUnmounted(() => {
76
- if (clickTimer.value !== null) {
77
- clearTimeout(clickTimer.value);
78
- }
79
- if (countdownTimer.value !== null) {
80
- clearInterval(countdownTimer.value);
81
- }
82
- });
83
-
84
- const handleClick = (event: MouseEvent) => {
85
- if (!props.disabled && !props.loading && !isCountingDown.value) {
86
- if (clickTimer.value !== null) {
87
- clearTimeout(clickTimer.value);
88
- }
89
- if (countdownTimer.value !== null) {
90
- clearInterval(countdownTimer.value);
91
- }
92
- isCountingDown.value = true;
93
- countdown.value = props.stabilizationTime;
94
-
95
- emit('click', event);
96
-
97
- if (countdown.value > 0) {
98
- emit('countdown', { remaining: countdown.value, total: props.stabilizationTime });
99
-
100
- countdownTimer.value = window.setInterval(() => {
101
- if (countdown.value > 0) {
102
- countdown.value -= props.degressionTime;
103
- emit('countdown', { remaining: countdown.value, total: props.stabilizationTime });
104
- }
105
-
106
- if (countdown.value <= 0) {
107
- clearInterval(countdownTimer.value!);
108
- isCountingDown.value = false;
109
- emit('countdown', { remaining: 0, total: props.stabilizationTime });
110
- }
111
- }, props.intervalUpdateTime);
112
- clickTimer.value = window.setTimeout(() => {
113
- isCountingDown.value = false;
114
- }, props.stabilizationTime);
115
- } else {
116
- isCountingDown.value = false;
117
- }
118
- }
119
- };
120
- </script>
121
-
122
- <style lang="scss">
123
- .v-button {
124
- width: 150rpx;
125
- height: 50rpx;
126
- border: none;
127
- cursor: pointer;
128
- transition: all 0.3s;
129
- display: flex;
130
- align-items: center;
131
- justify-content: center;
132
- color: white;
133
-
134
- &:hover {
135
- opacity: v-bind('config.opacity.hover');
136
- }
137
-
138
- &:active {
139
- opacity: v-bind('config.opacity.click');
140
- }
141
-
142
- &--semicircle {
143
- border-radius: v-bind('config.borderRadius.semicircle');
144
- }
145
-
146
- &--square {
147
- border-radius: v-bind('config.borderRadius.square');
148
- }
149
-
150
- &--circle {
151
- border-radius: v-bind('config.borderRadius.circle');
152
- }
153
-
154
- &--border {
155
- border-radius: 0;
156
- border-bottom: 1rpx solid v-bind('config.border.color');
157
- }
158
-
159
- &--default {
160
- background-color: v-bind('config.backgroundColor.default') !important;
161
- }
162
-
163
- &--delete {
164
- background-color: v-bind('config.backgroundColor.delete') !important;
165
- }
166
-
167
- &--succeed {
168
- background-color: v-bind('config.backgroundColor.succeed') !important;
169
- }
170
-
171
- &--info {
172
- background-color: v-bind('config.backgroundColor.info') !important;
173
- }
174
-
175
- &--warn {
176
- background-color: v-bind('config.backgroundColor.warn') !important;
177
- }
178
-
179
- &--text {
180
- background-color: v-bind('config.backgroundColor.reversal') !important;
181
- color: v-bind('config.fontColor.text');
182
- }
183
-
184
- &--small {
185
- width: 120rpx;
186
- height: 50rpx;
187
- padding: 14rpx 2rpx;
188
- font-size: v-bind("config.fontSize.smallText");
189
- }
190
-
191
- &--medium {
192
- width: 150rpx;
193
- height: 60rpx;
194
- padding: 15rpx 0;
195
- font-size: v-bind("config.fontSize.mediumText");
196
- }
197
-
198
- &--large {
199
- width: 170rpx;
200
- height: 70rpx;
201
- padding: 20rpx 0;
202
- font-size: v-bind("config.fontSize.largeText");
203
- }
204
-
205
- &--disabled,
206
- &[disabled] {
207
- opacity: v-bind('config.opacity.disabled');
208
- cursor: not-allowed;
209
- color: v-bind('config.fontColor.reversal') !important;
210
- }
211
-
212
- &--loading {
213
- position: relative;
214
- overflow: hidden;
215
- }
216
-
217
- &--plain {
218
- background-color: transparent !important;
219
- border: 1rpx solid;
220
- color: currentColor;
221
-
222
- &.v-button--default {
223
- border-color: v-bind("config.border.default");
224
- color: v-bind("config.fontColor.default");
225
- }
226
-
227
- &.v-button--delete {
228
- border-color: v-bind("config.border.delete");
229
- color: v-bind("config.fontColor.delete");
230
- }
231
-
232
- &.v-button--succeed {
233
- border-color: v-bind("config.border.succeed");
234
- color: v-bind("config.fontColor.succeed");
235
- }
236
-
237
- &.v-button--info {
238
- border-color: v-bind("config.border.info");
239
- color: v-bind("config.fontColor.info");
240
- }
241
-
242
- &.v-button--warn {
243
- border-color: v-bind("config.border.warn");
244
- color: v-bind("config.fontColor.warn");
245
- }
246
-
247
- &.v-button--text {
248
- border: none;
249
- color: v-bind("config.fontColor.text");
250
- }
251
- }
252
-
253
- .spinner {
254
- width: 20rpx;
255
- height: 20rpx;
256
- border: 1rpx solid;
257
- border-color: v-bind("config.border.color");
258
- border-radius: 50%;
259
- border-top-color: white;
260
- animation: spin 1s ease-in-out infinite;
261
- }
262
-
263
- @keyframes spin {
264
- to {
265
- transform: rotate(360deg);
266
- }
267
- }
268
- }
269
-
270
- uni-button:after {
271
- border: none;
272
- }
273
- </style>
@@ -1,138 +0,0 @@
1
- <template>
2
- <view class="carousel-box">
3
- <!-- 左右箭头 -->
4
- <view class="carousel-nav-buttons" v-show="isEndsButton">
5
- <view class="carousel-nav-buttons-prev" @click="prevSlide">
6
- <slot name="prev-button">
7
- <view class="default-prev-button">←</view>
8
- </slot>
9
- </view>
10
- <view class="carousel-nav-buttons-next" @click="nextSlide">
11
- <slot name="next-button">
12
- <view class="default-next-button">→</view>
13
- </slot>
14
- </view>
15
- </view>
16
-
17
- <!-- 关键改动 1:key 强制重建 -->
18
- <swiper
19
- :key="carouselKey"
20
- :indicator-dots="indicatorDots"
21
- :autoplay="autoplay"
22
- :interval="interval"
23
- :duration="duration"
24
- :current="currentVal"
25
- :circular="circular"
26
- @change="onSwiperChange"
27
- class="swiper-box"
28
- >
29
- <swiper-item v-for="(item, index) in items" :key="index" class="carousel-item">
30
- <slot :name="'item-' + index" :item="item"></slot>
31
- </swiper-item>
32
- </swiper>
33
- </view>
34
- </template>
35
-
36
- <script setup lang="ts">
37
- import { ref, watch, inject } from 'vue';
38
-
39
- const props = defineProps({
40
- items: { type: Array, default: () => [] },
41
- indicatorDots: { type: Boolean, default: true },
42
- autoplay: { type: Boolean, default: true },
43
- interval: { type: Number, default: 5000 },
44
- duration: { type: Number, default: 400 },
45
- current: { type: Number, default: 0 },
46
- isEndsButton: { type: Boolean, default: false },
47
- circular: { type: Boolean, default: true }
48
- });
49
-
50
- const emit = defineEmits(['update:current', 'change']);
51
- const config = inject<any>('config');
52
-
53
- const currentVal = ref(props.current);
54
- const carouselKey = ref(0); // 关键改动 2:刷新 key
55
-
56
- /* 双向绑定 current */
57
- watch(
58
- () => props.current,
59
- (v) => (currentVal.value = v),
60
- { immediate: true }
61
- );
62
- watch(currentVal, (v) => emit('update:current', v));
63
-
64
- /* 关键改动 3:节流防止抽搐 */
65
- let changing = false;
66
- const onSwiperChange = (e: any) => {
67
- if (changing) return;
68
- changing = true;
69
- const { current } = e.detail;
70
- currentVal.value = current;
71
- emit('change', current);
72
- setTimeout(() => (changing = false), 150);
73
- };
74
-
75
- /* 手动切换 */
76
- const prevSlide = () => {
77
- const len = props.items.length;
78
- currentVal.value = currentVal.value <= 0 ? len - 1 : currentVal.value - 1;
79
- emit('change', currentVal.value);
80
- };
81
- const nextSlide = () => {
82
- const len = props.items.length;
83
- currentVal.value = currentVal.value >= len - 1 ? 0 : currentVal.value + 1;
84
- emit('change', currentVal.value);
85
- };
86
- </script>
87
-
88
- <style lang="scss" scoped>
89
- .carousel-box {
90
- width: 100%;
91
- /* 关键改动 4:禁止百分比高度,用固定值 */
92
- height: 560rpx;
93
- position: relative;
94
- }
95
-
96
- .carousel-nav-buttons {
97
- position: absolute;
98
- width: 90%;
99
- top: 50%;
100
- transform: translateY(-50%);
101
- display: flex;
102
- justify-content: space-between;
103
- padding: 0 10rpx;
104
- z-index: 10;
105
- }
106
-
107
- .carousel-nav-buttons-prev,
108
- .carousel-nav-buttons-next {
109
- display: flex;
110
- align-items: center;
111
- justify-content: center;
112
- width: 40rpx;
113
- height: 40rpx;
114
- border-radius: 50%;
115
- background-color: rgba(255, 255, 255, 0.5);
116
- cursor: pointer;
117
- user-select: none;
118
- }
119
-
120
- .default-prev-button,
121
- .default-next-button {
122
- font-size: v-bind('config.fontSize.largeText');
123
- color: v-bind('config.fontColor.mainText');
124
- }
125
-
126
- .swiper-box {
127
- width: 100%;
128
- height: 100%;
129
- }
130
-
131
- .carousel-item {
132
- width: 100%;
133
- height: 100%;
134
- display: flex;
135
- justify-content: center;
136
- align-items: center;
137
- }
138
- </style>
@@ -1,215 +0,0 @@
1
- <template>
2
- <label :class="['v-checkbox', { 'v-checkbox--disabled': isDisabled, 'v-checkbox--checked': isChecked, 'v-checkbox--indeterminate': isIndeterminate }]" @click="handleChange">
3
- <span class="v-checkbox-input">
4
- <span v-if="isChecked" class="v-checkbox-inner"></span>
5
- </span>
6
- <span class="v-checkbox-label">
7
- <slot>{{ item.label }}</slot>
8
- </span>
9
- </label>
10
- </template>
11
-
12
- <script setup lang="ts">
13
- import { ref, watch, inject, computed } from 'vue';
14
-
15
- interface CheckboxItem {
16
- label: string;
17
- value: string | number | IndeterminateValue;
18
- }
19
-
20
- interface IndeterminateValue {
21
- S: string | number | null;
22
- A: string | number | null;
23
- M: string | number | null;
24
- }
25
-
26
- const props = defineProps({
27
- value: {
28
- type: Array,
29
- default: () => []
30
- },
31
- item: {
32
- type: Object as () => CheckboxItem,
33
- required: true
34
- },
35
- disabled: {
36
- type: Boolean,
37
- default: false
38
- },
39
- indeterminate: {
40
- type: Boolean,
41
- default: false
42
- }
43
- });
44
-
45
- const emit = defineEmits(['update:value', 'change']);
46
-
47
- const checkboxGroup = inject('checkboxGroup', null);
48
-
49
- const isChecked = computed(() => {
50
- return checkboxGroup ? checkboxGroup.checkedValues.value.some((value: any) => deepEqual(value, props.item.value)) : props.value.some((v) => deepEqual(v, props.item.value));
51
- });
52
-
53
- const isDisabled = computed(() => {
54
- return checkboxGroup ? checkboxGroup.disabled.value || props.disabled : props.disabled;
55
- });
56
-
57
- const isIndeterminate = ref(props.indeterminate);
58
-
59
- const deepEqual = (x: any, y: any): boolean => {
60
- if (x === y) return true;
61
-
62
- if (typeof x === 'object' && x !== null && typeof y === 'object' && y !== null) {
63
- if (Array.isArray(x)) {
64
- if (!Array.isArray(y) || x.length !== y.length) return false;
65
- return x.every((item, index) => deepEqual(item, y[index]));
66
- }
67
-
68
- const xKeys = Object.keys(x);
69
- const yKeys = Object.keys(y);
70
- if (xKeys.length !== yKeys.length) return false;
71
-
72
- return xKeys.every((key) => {
73
- return y.hasOwnProperty(key) && deepEqual(x[key], y[key]);
74
- });
75
- }
76
-
77
- return false;
78
- };
79
-
80
- watch(
81
- () => props.value,
82
- (newVal) => {
83
- isChecked.value = newVal.some((v) => deepEqual(v, props.item.value));
84
- },
85
- { deep: true }
86
- );
87
-
88
- watch(
89
- () => props.indeterminate,
90
- (newVal) => {
91
- isIndeterminate.value = newVal;
92
- }
93
- );
94
-
95
- const handleChange = () => {
96
- if (isDisabled.value) return;
97
-
98
- let newValues = [...(checkboxGroup ? checkboxGroup.checkedValues.value : props.value)];
99
- const currentValue = props.item.value;
100
-
101
- if (checkboxGroup && checkboxGroup.indeterminate) {
102
- if (!isChecked.value && !isIndeterminate.value) {
103
- newValues.push(currentValue);
104
- } else if (isChecked.value && !isIndeterminate.value) {
105
- newValues = newValues.filter((v) => !deepEqual(v, currentValue));
106
- }
107
- } else {
108
- if (isChecked.value) {
109
- newValues = newValues.filter((v) => !deepEqual(v, currentValue));
110
- } else if (isIndeterminate.value) {
111
- newValues.push(currentValue);
112
- isIndeterminate.value = false;
113
- } else {
114
- isIndeterminate.value = true;
115
- }
116
- }
117
-
118
- if (checkboxGroup) {
119
- checkboxGroup.checkedValues.value = [...new Set(newValues)];
120
- } else {
121
- emit('update:value', [...new Set(newValues)]);
122
- emit('change', [...new Set(newValues)]);
123
- }
124
- };
125
- </script>
126
-
127
- <style lang="scss" scoped>
128
- .v-checkbox {
129
- display: flex;
130
- align-items: center;
131
- cursor: pointer;
132
- font-size: 14px;
133
- color: #606266;
134
- transition: all 0.3s;
135
- margin-right: 16px;
136
-
137
- &:last-child {
138
- margin-right: 0;
139
- }
140
-
141
- &--disabled {
142
- color: #c0c4cc;
143
- cursor: not-allowed;
144
-
145
- .v-checkbox-input {
146
- background-color: #f5f7fa;
147
- border-color: #e4e7ed;
148
- cursor: not-allowed;
149
- }
150
- }
151
-
152
- &--checked {
153
- .v-checkbox-input {
154
- border-color: #287afa !important;
155
-
156
- .v-checkbox-inner {
157
- background-color: #287afa !important;
158
- display: block !important;
159
- }
160
- }
161
- }
162
-
163
- &--indeterminate {
164
- .v-checkbox-input {
165
- border-color: #287afa !important;
166
- background-color: #f5f7fa !important;
167
-
168
- &::after {
169
- display: block;
170
- }
171
- }
172
- }
173
-
174
- .v-checkbox-input {
175
- display: inline-block;
176
- width: 16px;
177
- height: 16px;
178
- border: 1px solid #dcdfe6;
179
- border-radius: 2px;
180
- background-color: #fff;
181
- position: relative;
182
- margin-right: 8px;
183
- cursor: pointer;
184
- transition: all 0.3s;
185
- vertical-align: middle;
186
-
187
- .v-checkbox-inner {
188
- display: none;
189
- width: 12px;
190
- height: 12px;
191
- position: absolute;
192
- left: 50%;
193
- top: 50%;
194
- transform: translate(-50%, -50%);
195
- }
196
-
197
- &::after {
198
- content: '';
199
- display: none;
200
- position: absolute;
201
- left: 5px;
202
- top: 1px;
203
- width: 6px;
204
- height: 12px;
205
- border: solid #287afa;
206
- border-width: 0 2px 2px 0;
207
- transform: rotate(45deg);
208
- }
209
- }
210
-
211
- .v-checkbox-label {
212
- display: inline-block;
213
- }
214
- }
215
- </style>