| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- <template>
- <view class="base-loading" :class="{ 'base-loading--overlay': overlay }" v-if="loading">
- <view class="base-loading__spinner" v-if="type === 'spinner'">
- <view class="base-loading__dot" v-for="i in 3" :key="i"></view>
- </view>
- <text class="base-loading__text" v-if="text">{{ text }}</text>
- </view>
- </template>
- <script>
- export default {
- name: 'BaseLoading',
- props: {
- loading: { type: Boolean, default: false },
- type: { type: String, default: 'spinner' },
- // 'spinner' | 'skeleton'
- text: { type: String, default: '' },
- overlay: { type: Boolean, default: false }
- }
- }
- </script>
- <style scoped>
- .base-loading {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- padding: 48rpx;
- }
- .base-loading--overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(255, 255, 255, 0.8);
- z-index: 999;
- padding: 0;
- }
- /* Spinner dots */
- .base-loading__spinner {
- display: flex;
- align-items: center;
- gap: 12rpx;
- margin-bottom: 16rpx;
- }
- .base-loading__dot {
- width: 16rpx;
- height: 16rpx;
- border-radius: 50%;
- background: var(--color-primary, #F97316);
- animation: dot-bounce 1.2s ease-in-out infinite;
- }
- .base-loading__dot:nth-child(2) { animation-delay: 0.2s; }
- .base-loading__dot:nth-child(3) { animation-delay: 0.4s; }
- .base-loading__text {
- font-size: 24rpx;
- color: var(--muted, #94A3B8);
- }
- @keyframes dot-bounce {
- 0%, 80%, 100% {
- transform: scale(0.6);
- opacity: 0.4;
- }
- 40% {
- transform: scale(1);
- opacity: 1;
- }
- }
- </style>
|