1. 新增splash-screen全局启动屏组件,适配非APP平台的加载过渡 2. 新增splash-state状态管理模块,统一处理启动屏的显示隐藏、软隐藏时序、兜底超时逻辑 3. 重构App.vue和main.js的加载逻辑,替换原有uni.showLoading方案 4. 在首页和空页面挂载启动屏组件,适配不同页面场景 5. 兼容H5平台降级处理,解决main.js挂载前无法渲染组件的问题
179 lines
3.5 KiB
Vue
179 lines
3.5 KiB
Vue
<template>
|
|
<!-- #ifndef APP-PLUS -->
|
|
<view v-if="visible" class="splash-screen" :class="{ 'splash-screen--leaving': leaving }">
|
|
<view class="splash-screen__bg"></view>
|
|
<view class="splash-screen__content">
|
|
<view class="splash-screen__logo">
|
|
<view class="splash-screen__logo-inner">S</view>
|
|
</view>
|
|
<view class="splash-screen__name">Shop</view>
|
|
<view class="splash-screen__loader">
|
|
<view class="splash-screen__dot"></view>
|
|
<view class="splash-screen__dot"></view>
|
|
<view class="splash-screen__dot"></view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<!-- #endif -->
|
|
</template>
|
|
|
|
<script>
|
|
import splashState from '@/common/js/splash-state.js';
|
|
|
|
export default {
|
|
name: 'splash-screen',
|
|
data() {
|
|
return {
|
|
visible: false,
|
|
leaving: false
|
|
};
|
|
},
|
|
mounted() {
|
|
// 1) 启动时同步读取状态 (防止 mount 前已经 hide 的情况)
|
|
if (splashState.isShow()) {
|
|
this.visible = true;
|
|
}
|
|
// 2) 通知 state 模块: 组件已 mount
|
|
// 如果此时 splashState 有 _pendingHide (软隐藏), 会触发真关
|
|
splashState.notifyMounted();
|
|
// 3) 监听后续事件
|
|
splashState.on('splash:show', () => {
|
|
this.visible = true;
|
|
this.leaving = false;
|
|
});
|
|
splashState.on('splash:hide', () => {
|
|
this._leave();
|
|
});
|
|
},
|
|
beforeDestroy() {
|
|
splashState.off('splash:show');
|
|
splashState.off('splash:hide');
|
|
splashState.notifyUnmounted();
|
|
if (this._leaveTimer) {
|
|
clearTimeout(this._leaveTimer);
|
|
this._leaveTimer = null;
|
|
}
|
|
},
|
|
methods: {
|
|
_leave() {
|
|
// 触发淡出动画,动画结束再 unmount
|
|
this.leaving = true;
|
|
if (this._leaveTimer) clearTimeout(this._leaveTimer);
|
|
this._leaveTimer = setTimeout(() => {
|
|
this.visible = false;
|
|
this.leaving = false;
|
|
}, 320);
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.splash-screen {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
z-index: 99999;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
opacity: 1;
|
|
transition: opacity 0.3s ease;
|
|
|
|
&--leaving {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
.splash-screen__bg {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: linear-gradient(180deg, #ffffff 0%, #f7f7f7 100%);
|
|
}
|
|
|
|
.splash-screen__content {
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.splash-screen__logo {
|
|
width: 96rpx;
|
|
height: 96rpx;
|
|
border-radius: 24rpx;
|
|
background: #FF0036;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
box-shadow: 0 8rpx 24rpx rgba(255, 0, 54, 0.18);
|
|
animation: splash-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) both;
|
|
}
|
|
|
|
.splash-screen__logo-inner {
|
|
color: #fff;
|
|
font-size: 56rpx;
|
|
font-weight: 700;
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', sans-serif;
|
|
}
|
|
|
|
.splash-screen__name {
|
|
margin-top: 28rpx;
|
|
font-size: 32rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
letter-spacing: 1rpx;
|
|
}
|
|
|
|
.splash-screen__loader {
|
|
margin-top: 48rpx;
|
|
display: flex;
|
|
gap: 12rpx;
|
|
}
|
|
|
|
.splash-screen__dot {
|
|
width: 12rpx;
|
|
height: 12rpx;
|
|
border-radius: 50%;
|
|
background: #FF0036;
|
|
opacity: 0.4;
|
|
animation: splash-bounce 1.2s ease-in-out infinite;
|
|
|
|
&:nth-child(2) {
|
|
animation-delay: 0.15s;
|
|
}
|
|
|
|
&:nth-child(3) {
|
|
animation-delay: 0.3s;
|
|
}
|
|
}
|
|
|
|
@keyframes splash-pop {
|
|
0% {
|
|
transform: scale(0.6);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
transform: scale(1);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes splash-bounce {
|
|
0%, 80%, 100% {
|
|
transform: scale(0.7);
|
|
opacity: 0.4;
|
|
}
|
|
40% {
|
|
transform: scale(1);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
</style>
|