muzhiyu-ui 1.0.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.
Files changed (96) hide show
  1. package/README.md +202 -0
  2. package/components/muzhiyu/mu-action-sheet/mu-action-sheet.vue +335 -0
  3. package/components/muzhiyu/mu-alert/mu-alert.vue +220 -0
  4. package/components/muzhiyu/mu-back-top/mu-back-top.vue +161 -0
  5. package/components/muzhiyu/mu-badge/mu-badge.vue +150 -0
  6. package/components/muzhiyu/mu-barcode/mu-barcode.vue +100 -0
  7. package/components/muzhiyu/mu-blank/mu-blank.vue +30 -0
  8. package/components/muzhiyu/mu-bottom-nav/mu-bottom-nav.vue +331 -0
  9. package/components/muzhiyu/mu-bubble/mu-bubble.vue +316 -0
  10. package/components/muzhiyu/mu-button/mu-button.vue +431 -0
  11. package/components/muzhiyu/mu-calendar/mu-calendar.vue +429 -0
  12. package/components/muzhiyu/mu-car-input/mu-car-input.vue +209 -0
  13. package/components/muzhiyu/mu-card/mu-card.vue +317 -0
  14. package/components/muzhiyu/mu-cascader/mu-cascader.vue +336 -0
  15. package/components/muzhiyu/mu-cell/mu-cell.vue +368 -0
  16. package/components/muzhiyu/mu-checkbox/mu-checkbox.vue +116 -0
  17. package/components/muzhiyu/mu-checkbox-group/mu-checkbox-group.vue +40 -0
  18. package/components/muzhiyu/mu-code-input/mu-code-input.vue +264 -0
  19. package/components/muzhiyu/mu-collapse/mu-collapse.vue +316 -0
  20. package/components/muzhiyu/mu-color-picker/mu-color-picker.vue +466 -0
  21. package/components/muzhiyu/mu-config/index.js +34 -0
  22. package/components/muzhiyu/mu-config/mu-config.vue +54 -0
  23. package/components/muzhiyu/mu-countdown/mu-countdown.vue +338 -0
  24. package/components/muzhiyu/mu-cropper/mu-cropper.vue +415 -0
  25. package/components/muzhiyu/mu-date-picker/mu-date-picker.vue +290 -0
  26. package/components/muzhiyu/mu-datetime/mu-datetime.vue +262 -0
  27. package/components/muzhiyu/mu-divider/mu-divider.vue +229 -0
  28. package/components/muzhiyu/mu-drawer/mu-drawer.vue +172 -0
  29. package/components/muzhiyu/mu-dropdown/mu-dropdown.vue +215 -0
  30. package/components/muzhiyu/mu-dropdown-top/mu-dropdown-top.vue +243 -0
  31. package/components/muzhiyu/mu-empty/mu-empty.vue +217 -0
  32. package/components/muzhiyu/mu-fab/mu-fab.vue +324 -0
  33. package/components/muzhiyu/mu-footer/mu-footer.vue +21 -0
  34. package/components/muzhiyu/mu-form/mu-form.vue +170 -0
  35. package/components/muzhiyu/mu-grid/mu-grid.vue +95 -0
  36. package/components/muzhiyu/mu-grid-item/mu-grid-item.vue +247 -0
  37. package/components/muzhiyu/mu-html/mu-html.vue +145 -0
  38. package/components/muzhiyu/mu-icon/mu-icon.vue +822 -0
  39. package/components/muzhiyu/mu-image-grid/mu-image-grid.vue +225 -0
  40. package/components/muzhiyu/mu-image-preview/mu-image-preview.vue +286 -0
  41. package/components/muzhiyu/mu-index-list/mu-index-list.vue +381 -0
  42. package/components/muzhiyu/mu-input/mu-input.vue +570 -0
  43. package/components/muzhiyu/mu-input-number/mu-input-number.vue +193 -0
  44. package/components/muzhiyu/mu-keyboard/mu-keyboard.vue +415 -0
  45. package/components/muzhiyu/mu-list/mu-list.vue +89 -0
  46. package/components/muzhiyu/mu-loading/mu-loading.vue +124 -0
  47. package/components/muzhiyu/mu-loading-page/mu-loading-page.vue +529 -0
  48. package/components/muzhiyu/mu-loadmore/mu-loadmore.vue +26 -0
  49. package/components/muzhiyu/mu-modal/mu-modal.vue +298 -0
  50. package/components/muzhiyu/mu-navbar/mu-navbar.vue +223 -0
  51. package/components/muzhiyu/mu-nomore/mu-nomore.vue +107 -0
  52. package/components/muzhiyu/mu-notice-bar/mu-notice-bar.vue +284 -0
  53. package/components/muzhiyu/mu-notify/mu-notify.vue +202 -0
  54. package/components/muzhiyu/mu-overlay/mu-overlay.vue +94 -0
  55. package/components/muzhiyu/mu-pagination/mu-pagination.vue +330 -0
  56. package/components/muzhiyu/mu-password-input/mu-password-input.vue +119 -0
  57. package/components/muzhiyu/mu-picker/mu-picker.vue +297 -0
  58. package/components/muzhiyu/mu-popup/mu-popup.vue +297 -0
  59. package/components/muzhiyu/mu-progress/mu-progress.vue +156 -0
  60. package/components/muzhiyu/mu-pull-refresh/mu-pull-refresh.vue +54 -0
  61. package/components/muzhiyu/mu-qrcode/mu-qrcode.vue +340 -0
  62. package/components/muzhiyu/mu-qrcode/qrcode.js +2237 -0
  63. package/components/muzhiyu/mu-radio/mu-radio.vue +125 -0
  64. package/components/muzhiyu/mu-radio-group/mu-radio-group.vue +37 -0
  65. package/components/muzhiyu/mu-rate/mu-rate.vue +103 -0
  66. package/components/muzhiyu/mu-search/mu-search.vue +320 -0
  67. package/components/muzhiyu/mu-section/mu-section.vue +206 -0
  68. package/components/muzhiyu/mu-select/mu-select.vue +440 -0
  69. package/components/muzhiyu/mu-share-sheet/mu-share-sheet.vue +269 -0
  70. package/components/muzhiyu/mu-sidebar/mu-sidebar.vue +304 -0
  71. package/components/muzhiyu/mu-signature/mu-signature.vue +449 -0
  72. package/components/muzhiyu/mu-skeleton/mu-skeleton.vue +225 -0
  73. package/components/muzhiyu/mu-slider/mu-slider.vue +228 -0
  74. package/components/muzhiyu/mu-space/mu-space.vue +84 -0
  75. package/components/muzhiyu/mu-steps/mu-steps.vue +311 -0
  76. package/components/muzhiyu/mu-sticky/mu-sticky.vue +57 -0
  77. package/components/muzhiyu/mu-swipe-cell/mu-swipe-cell.vue +281 -0
  78. package/components/muzhiyu/mu-swiper/mu-swiper.vue +107 -0
  79. package/components/muzhiyu/mu-switch/mu-switch.vue +99 -0
  80. package/components/muzhiyu/mu-tabbar/mu-tabbar.vue +382 -0
  81. package/components/muzhiyu/mu-table/mu-table.vue +420 -0
  82. package/components/muzhiyu/mu-tabs/mu-tabs.vue +339 -0
  83. package/components/muzhiyu/mu-tag/mu-tag.vue +65 -0
  84. package/components/muzhiyu/mu-text-ellipsis/mu-text-ellipsis.vue +54 -0
  85. package/components/muzhiyu/mu-timeline/mu-timeline.vue +166 -0
  86. package/components/muzhiyu/mu-tips/mu-tips.vue +36 -0
  87. package/components/muzhiyu/mu-toast/mu-toast.vue +151 -0
  88. package/components/muzhiyu/mu-transfer/mu-transfer.vue +114 -0
  89. package/components/muzhiyu/mu-tree/mu-tree.vue +263 -0
  90. package/components/muzhiyu/mu-upload/mu-upload.vue +415 -0
  91. package/components/muzhiyu/mu-waterfall/mu-waterfall.vue +321 -0
  92. package/components/muzhiyu/mu-watermark/mu-watermark.vue +60 -0
  93. package/index.js +83 -0
  94. package/package.json +38 -0
  95. package/utils/index.js +600 -0
  96. package/utils/request.js +265 -0
@@ -0,0 +1,330 @@
1
+ <template>
2
+ <view class="mu-pagination" :class="[`mu-pagination--${mode}`, `mu-pagination--${shape}`]">
3
+ <!-- 移动端轻量模式 simple (上一页 1/10 下一页) -->
4
+ <template v-if="mode === 'simple'">
5
+ <view
6
+ class="mu-pagination__btn mu-pagination__prev mu-touchable-flat"
7
+ :class="[current <= 1 && 'mu-pagination__btn--disabled']"
8
+ @tap="goTo(current - 1)"
9
+ >
10
+ <mu-icon name="chevron_left" :size="14" :color="current <= 1 ? '#CBD5E1' : '#171717'" />
11
+ <text class="mu-pagination__btn-text">{{ prevText }}</text>
12
+ </view>
13
+
14
+ <view class="mu-pagination__simple-text">
15
+ <text class="mu-pagination__simple-current">{{ current }}</text>
16
+ <text class="mu-pagination__simple-sep">/</text>
17
+ <text class="mu-pagination__simple-total">{{ totalPage }}</text>
18
+ </view>
19
+
20
+ <view
21
+ class="mu-pagination__btn mu-pagination__next mu-touchable-flat"
22
+ :class="[current >= totalPage && 'mu-pagination__btn--disabled']"
23
+ @tap="goTo(current + 1)"
24
+ >
25
+ <text class="mu-pagination__btn-text">{{ nextText }}</text>
26
+ <mu-icon name="chevron_right" :size="14" :color="current >= totalPage ? '#CBD5E1' : '#171717'" />
27
+ </view>
28
+ </template>
29
+
30
+ <!-- 数字按钮页码模式 multi -->
31
+ <template v-else-if="mode === 'multi'">
32
+ <view
33
+ class="mu-pagination__btn mu-pagination__prev mu-touchable-flat"
34
+ :class="[current <= 1 && 'mu-pagination__btn--disabled']"
35
+ @tap="goTo(current - 1)"
36
+ >
37
+ <mu-icon name="chevron_left" :size="14" :color="current <= 1 ? '#CBD5E1' : '#64748B'" />
38
+ </view>
39
+
40
+ <view
41
+ v-for="(page, pi) in pages"
42
+ :key="pi"
43
+ class="mu-pagination__page"
44
+ :class="[
45
+ page === current && 'mu-pagination__page--active',
46
+ page === '...' && 'mu-pagination__page--ellipsis'
47
+ ]"
48
+ @tap="page !== '...' && goTo(page)"
49
+ >
50
+ <text class="mu-pagination__page-text">{{ page }}</text>
51
+ </view>
52
+
53
+ <view
54
+ class="mu-pagination__btn mu-pagination__next mu-touchable-flat"
55
+ :class="[current >= totalPage && 'mu-pagination__btn--disabled']"
56
+ @tap="goTo(current + 1)"
57
+ >
58
+ <mu-icon name="chevron_right" :size="14" :color="current >= totalPage ? '#CBD5E1' : '#64748B'" />
59
+ </view>
60
+ </template>
61
+
62
+ <!-- 指示点模式 pointer (比如卡片/轮播辅助) -->
63
+ <template v-else-if="mode === 'pointer'">
64
+ <view
65
+ v-for="p in totalPage"
66
+ :key="p"
67
+ class="mu-pagination__pointer"
68
+ :class="[p === current && 'mu-pagination__pointer--active']"
69
+ @tap="goTo(p)"
70
+ ></view>
71
+ </template>
72
+ </view>
73
+ </template>
74
+
75
+ <script setup>
76
+ import { computed } from 'vue'
77
+
78
+ const props = defineProps({
79
+ current: { type: Number, default: 1 },
80
+ modelValue: { type: Number, default: 0 },
81
+ total: { type: Number, default: 0 },
82
+ pageSize: { type: Number, default: 10 },
83
+ pageCount: { type: Number, default: 0 }, // 直接指定总页数
84
+ maxPages: { type: Number, default: 5 }, // 最多显示的页码数
85
+ mode: { type: String, default: 'multi' }, // multi (数字页码) | simple (移动端上一页/下一页) | pointer (圆点)
86
+ shape: { type: String, default: 'radius' }, // radius (微圆角) | circle (全圆)
87
+ prevText: { type: String, default: '上一页' },
88
+ nextText: { type: String, default: '下一页' }
89
+ })
90
+
91
+ const emit = defineEmits(['change', 'update:current', 'update:modelValue'])
92
+
93
+ const current = computed({
94
+ get: () => props.modelValue || props.current || 1,
95
+ set: (val) => {
96
+ emit('update:current', val)
97
+ emit('update:modelValue', val)
98
+ }
99
+ })
100
+
101
+ const totalPage = computed(() => {
102
+ if (props.pageCount > 0) return props.pageCount
103
+ if (props.total > 0) return Math.ceil(props.total / props.pageSize)
104
+ return 1
105
+ })
106
+
107
+ const pages = computed(() => {
108
+ const tp = totalPage.value
109
+ const cp = current.value
110
+ const max = props.maxPages
111
+
112
+ if (tp <= max) return Array.from({ length: tp }, (_, i) => i + 1)
113
+
114
+ const result = [1]
115
+ let start = Math.max(2, cp - Math.floor(max / 2))
116
+ let end = Math.min(tp - 1, start + max - 3)
117
+
118
+ start = Math.max(2, end - (max - 3))
119
+
120
+ if (start > 2) result.push('...')
121
+ for (let i = start; i <= end; i++) result.push(i)
122
+ if (end < tp - 1) result.push('...')
123
+
124
+ result.push(tp)
125
+ return result
126
+ })
127
+
128
+ function goTo(page) {
129
+ if (typeof page !== 'number') return
130
+ if (page < 1 || page > totalPage.value || page === current.value) return
131
+ current.value = page
132
+ emit('change', { current: page, totalPage: totalPage.value })
133
+ }
134
+ </script>
135
+
136
+ <style lang="scss" scoped>
137
+ @import "@/uni.scss";
138
+
139
+ .mu-pagination {
140
+ display: flex;
141
+ align-items: center;
142
+ justify-content: center;
143
+ gap: 12rpx;
144
+ box-sizing: border-box;
145
+
146
+ /* 1. 移动端轻量模式 simple */
147
+ &--simple {
148
+ justify-content: space-between;
149
+ width: 100%;
150
+
151
+ .mu-pagination__btn {
152
+ height: 64rpx;
153
+ padding: 0 24rpx;
154
+ background: #F8FAFC;
155
+ border: 1rpx solid rgba(226, 232, 240, 0.9);
156
+ border-radius: 14rpx;
157
+ display: flex;
158
+ align-items: center;
159
+ justify-content: center;
160
+ gap: 6rpx;
161
+
162
+ &-text {
163
+ font-size: 24rpx;
164
+ color: #171717;
165
+ font-weight: 700;
166
+ }
167
+ }
168
+
169
+ .mu-pagination__btn--disabled {
170
+ opacity: 0.5;
171
+ pointer-events: none;
172
+ .mu-pagination__btn-text {
173
+ color: #94A3B8;
174
+ }
175
+ }
176
+
177
+ .mu-pagination__simple-text {
178
+ font-size: 26rpx;
179
+ color: #64748B;
180
+ font-weight: 600;
181
+ font-variant-numeric: tabular-nums;
182
+ }
183
+
184
+ .mu-pagination__simple-current {
185
+ color: #171717;
186
+ font-weight: 800;
187
+ font-size: 28rpx;
188
+ }
189
+
190
+ .mu-pagination__simple-sep {
191
+ margin: 0 6rpx;
192
+ color: #CBD5E1;
193
+ }
194
+ }
195
+
196
+ /* 2. 数字页码模式 multi */
197
+ &--multi {
198
+ .mu-pagination__btn {
199
+ width: 64rpx;
200
+ height: 64rpx;
201
+ border-radius: 14rpx;
202
+ background: #F8FAFC;
203
+ border: 1rpx solid rgba(226, 232, 240, 0.9);
204
+ display: flex;
205
+ align-items: center;
206
+ justify-content: center;
207
+
208
+ &--disabled {
209
+ opacity: 0.4;
210
+ pointer-events: none;
211
+ }
212
+ }
213
+
214
+ .mu-pagination__page {
215
+ min-width: 64rpx;
216
+ height: 64rpx;
217
+ padding: 0 12rpx;
218
+ border-radius: 14rpx;
219
+ background: #ffffff;
220
+ border: 1rpx solid rgba(226, 232, 240, 0.9);
221
+ display: flex;
222
+ align-items: center;
223
+ justify-content: center;
224
+ box-sizing: border-box;
225
+
226
+ &-text {
227
+ font-size: 24rpx;
228
+ color: $mu-text-primary;
229
+ font-weight: 600;
230
+ font-variant-numeric: tabular-nums;
231
+ }
232
+
233
+ &--active {
234
+ background: #171717;
235
+ border-color: transparent;
236
+ box-shadow: 0 4rpx 14rpx rgba(99, 102, 241, 0.3);
237
+
238
+ .mu-pagination__page-text {
239
+ color: #ffffff;
240
+ font-weight: 800;
241
+ }
242
+ }
243
+
244
+ &--ellipsis {
245
+ border: none;
246
+ background: transparent;
247
+ .mu-pagination__page-text {
248
+ color: #94A3B8;
249
+ }
250
+ }
251
+ }
252
+ }
253
+
254
+ /* 3. 圆角定义 */
255
+ &--circle {
256
+ .mu-pagination__btn, .mu-pagination__page {
257
+ border-radius: 999rpx !important;
258
+ }
259
+ }
260
+
261
+ /* 4. 指示点模式 pointer */
262
+ &--pointer {
263
+ gap: 12rpx;
264
+
265
+ .mu-pagination__pointer {
266
+ width: 12rpx;
267
+ height: 12rpx;
268
+ border-radius: 50%;
269
+ background: rgba(148, 163, 184, 0.3);
270
+ transition: all 0.25s ease;
271
+
272
+ &--active {
273
+ width: 32rpx;
274
+ border-radius: 6rpx;
275
+ background: #171717;
276
+ }
277
+ }
278
+ }
279
+ }
280
+
281
+ .mu-dark, page.mu-dark {
282
+
283
+ .mu-pagination {
284
+ &--simple {
285
+ .mu-pagination__btn {
286
+ background: $mu-dark-bg-base;
287
+ border-color: rgba(255, 255, 255, 0.08);
288
+ }
289
+ .mu-pagination__simple-text { color: $mu-dark-text-secondary; }
290
+ }
291
+ &--multi {
292
+ .mu-pagination__btn, .mu-pagination__page {
293
+ background: $mu-dark-bg-base;
294
+ border-color: rgba(255, 255, 255, 0.08);
295
+ &-text { color: $mu-dark-text-primary; }
296
+ }
297
+ .mu-pagination__page--active {
298
+ background: #171717;
299
+ border-color: transparent;
300
+ .mu-pagination__page-text { color: #ffffff; }
301
+ }
302
+ }
303
+ }
304
+ }
305
+
306
+ @media (prefers-color-scheme: dark) {
307
+
308
+ .mu-pagination {
309
+ &--simple {
310
+ .mu-pagination__btn {
311
+ background: $mu-dark-bg-base;
312
+ border-color: rgba(255, 255, 255, 0.08);
313
+ }
314
+ .mu-pagination__simple-text { color: $mu-dark-text-secondary; }
315
+ }
316
+ &--multi {
317
+ .mu-pagination__btn, .mu-pagination__page {
318
+ background: $mu-dark-bg-base;
319
+ border-color: rgba(255, 255, 255, 0.08);
320
+ &-text { color: $mu-dark-text-primary; }
321
+ }
322
+ .mu-pagination__page--active {
323
+ background: #171717;
324
+ border-color: transparent;
325
+ .mu-pagination__page-text { color: #ffffff; }
326
+ }
327
+ }
328
+ }
329
+ }
330
+ </style>
@@ -0,0 +1,119 @@
1
+ <template>
2
+ <view class="mu-password-input">
3
+ <view class="mu-password-input__box" @tap="onFocus">
4
+ <view v-for="(item, i) in length" :key="i" class="mu-password-input__cell">
5
+ <view v-if="modelValue[i]" class="mu-password-input__dot" :class="{ 'mu-password-input__dot--square': !mask }">
6
+ <text v-if="!mask" class="mu-password-input__char">{{ modelValue[i] }}</text>
7
+ </view>
8
+ <view v-if="focused && i === modelValue.length" class="mu-password-input__cursor"></view>
9
+ </view>
10
+ </view>
11
+ <mu-keyboard v-if="!useSystemKeyboard" :show="focused" :maxlength="length"
12
+ v-model:value="innerValue" @close="focused = false" />
13
+ </view>
14
+ </template>
15
+
16
+ <script setup>
17
+ /**
18
+ * mu-password-input 密码输入框
19
+ * @description 密码/验证码输入,带安全键盘
20
+ * @property {string} modelValue - 输入值
21
+ * @property {number} length - 输入长度 4|6
22
+ * @property {boolean} mask - 是否密文
23
+ * @property {boolean} useSystemKeyboard - 使用系统键盘
24
+ */
25
+ import { ref, watch } from 'vue'
26
+
27
+ const props = defineProps({
28
+ modelValue: { type: String, default: '' },
29
+ length: { type: Number, default: 6 },
30
+ mask: { type: Boolean, default: true },
31
+ useSystemKeyboard: { type: Boolean, default: true }
32
+ })
33
+
34
+ const emit = defineEmits(['update:modelValue', 'finish', 'focus'])
35
+ const focused = ref(false)
36
+ const innerValue = ref(props.modelValue)
37
+
38
+ watch(() => props.modelValue, (v) => { innerValue.value = v })
39
+ watch(innerValue, (v) => {
40
+ emit('update:modelValue', v)
41
+ if (v.length >= props.length) emit('finish', v)
42
+ })
43
+
44
+ function onFocus() {
45
+ focused.value = true
46
+ emit('focus')
47
+ }
48
+ </script>
49
+
50
+ <style lang="scss" scoped>
51
+ .mu-password-input {
52
+ &__box {
53
+ display: flex; border: 1rpx solid $mu-border-color;
54
+ border-radius: $mu-radius-sm; overflow: hidden;
55
+ background: $mu-bg-base;
56
+ }
57
+ &__cell {
58
+ flex: 1; height: 96rpx;
59
+ display: flex; align-items: center; justify-content: center;
60
+ border-right: 1rpx solid $mu-border-light;
61
+ position: relative;
62
+ &:last-child { border-right: none; }
63
+ }
64
+ &__dot {
65
+ width: 20rpx; height: 20rpx; border-radius: 50%;
66
+ background: $mu-text-primary;
67
+ &--square {
68
+ width: auto; height: auto; background: none;
69
+ border-radius: 0;
70
+ }
71
+ }
72
+ &__char { font-size: $mu-font-xl; color: $mu-text-primary; font-weight: 600; }
73
+ &__cursor {
74
+ position: absolute; width: 2rpx; height: 40rpx;
75
+ background: $mu-primary;
76
+ animation: mu-blink 1s step-end infinite;
77
+ }
78
+ }
79
+ @keyframes mu-blink {
80
+ 0%, 100% { opacity: 1; }
81
+ 50% { opacity: 0; }
82
+ }
83
+
84
+ .mu-dark, page.mu-dark {
85
+ .mu-password-input {
86
+ &__box {
87
+ background: rgba(24, 24, 34, 0.95);
88
+ border-color: rgba(255, 255, 255, 0.12);
89
+ }
90
+ &__cell {
91
+ border-right-color: rgba(255, 255, 255, 0.08);
92
+ }
93
+ &__dot {
94
+ background: #F8FAFC;
95
+ }
96
+ &__char {
97
+ color: #F8FAFC;
98
+ }
99
+ }
100
+ }
101
+
102
+ @media (prefers-color-scheme: dark) {
103
+ .mu-password-input {
104
+ &__box {
105
+ background: rgba(24, 24, 34, 0.95);
106
+ border-color: rgba(255, 255, 255, 0.12);
107
+ }
108
+ &__cell {
109
+ border-right-color: rgba(255, 255, 255, 0.08);
110
+ }
111
+ &__dot {
112
+ background: #F8FAFC;
113
+ }
114
+ &__char {
115
+ color: #F8FAFC;
116
+ }
117
+ }
118
+ }
119
+ </style>