h5页面初始化

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">

       //这一行保证屏幕不能缩放
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
        <title></title>
    </head>
    <body>
        <script src="js/jquery3.3.1.js"></script>
        <script type="text/javascript">
            (function(){
                /*rem适配*/
                var html = document.documentElement;//获取根节点
                var width = html. ().width; //屏幕的设备独立像素                
                html.style.fontSize = width/15 + "px";
                //iphone5 320*568 则 fontSize为20px  也就是说 1rem=20px        
            })();
        </script>
    </body>
</html>

<think>我们已经在之前的讨论中给出了一个完整的加载动画实现方案。现在,用户希望在使用Vue3+TypeScript+Vite构建的H5页面中实现初始化加载动画。我们将结合引用中提到的Vite-Vue3-H5项目模板(引用[2][3])和Vite的特性(引用[1])来优化实现。 ### 实现思路 1. **创建加载动画组件**:使用SVG和CSS动画实现一个流畅的加载动画。 2. **全局控制**:在应用初始化时显示加载动画,在应用准备完成后隐藏。 3. **结合Vite特性**:利用Vite的快速启动和热更新优势,确保加载动画在开发和生产环境都能高效运行。 ### 具体实现步骤 #### 1. 创建加载动画组件 (src/components/Loading.vue) ```vue <template> <teleport to="body"> <div v-show="isLoading" class="loading-overlay"> <div class="loading-spinner"> <!-- SVG旋转动画 --> <svg viewBox="0 0 50 50" class="spinner"> <circle cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle> </svg> <p class="loading-text">{{ text }}</p> </div> </div> </teleport> </template> <script lang="ts"> import { defineComponent, ref } from 'vue'; export default defineComponent({ name: 'Loading', props: { text: { type: String, default: '加载中...' } }, setup() { const isLoading = ref(false); const show = () => isLoading.value = true; const hide = () => isLoading.value = false; // 暴露方法给父组件调用 return { isLoading, show, hide }; } }); </script> <style scoped> .loading-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.9); display: flex; justify-content: center; align-items: center; z-index: 9999; backdrop-filter: blur(2px); /* 毛玻璃效果 */ } .loading-spinner { text-align: center; } .spinner { width: 50px; height: 50px; animation: rotate 1.5s linear infinite; will-change: transform; /* 优化性能 */ } .spinner circle { stroke: #3eaf7c; /* 使用Vite的绿色主题色 */ stroke-linecap: round; stroke-dasharray: 90, 150; stroke-dashoffset: -35; animation: dash 1.5s ease-in-out infinite; } @keyframes rotate { 100% { transform: rotate(360deg); } } @keyframes dash { 0% { stroke-dasharray: 1, 150; stroke-dashoffset: 0; } 50% { stroke-dasharray: 90, 150; stroke-dashoffset: -35; } 100% { stroke-dasharray: 90, 150; stroke-dashoffset: -124; } } .loading-text { margin-top: 15px; color: #333; font-size: 16px; font-weight: 500; } </style> ``` #### 2. 在App.vue中使用加载动画组件 ```vue <template> <div id="app"> <!-- 加载动画组件 --> <Loading ref="loading" text="正在加载..." /> <!-- 主内容 --> <router-view v-show="appLoaded" /> </div> </template> <script lang="ts"> import { defineComponent, ref, onMounted } from 'vue'; import Loading from '@/components/Loading.vue'; export default defineComponent({ components: { Loading }, setup() { const loading = ref<InstanceType<typeof Loading> | null>(null); const appLoaded = ref(false); // 模拟应用初始化过程 const initApp = async () => { // 显示加载动画 loading.value?.show(); // 模拟初始化任务(如加载用户信息、获取配置等) await new Promise(resolve => setTimeout(resolve, 2000)); // 隐藏加载动画,显示主内容 loading.value?.hide(); appLoaded.value = true; }; onMounted(() => { initApp(); }); return { loading, appLoaded }; } }); </script> ``` #### 3. 优化:使用Vite的异步加载特性 在Vite项目中,我们可以结合动态导入优化资源加载: ```typescript // 在路由配置中使用动态导入 const routes = [ { path: '/', component: () => import('@/views/Home.vue'), meta: { title: '首页' } } ]; ``` ### 关键优化点(参考引用内容) 1. **REM/VW布局适配**(引用[3]): - 在项目中配置`postcss-pxtorem`实现自动单位转换 - 在`vite.config.ts`中配置: ```ts import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import postcsspxtorem from 'postcss-pxtorem'; export default defineConfig({ plugins: [vue()], css: { postcss: { plugins: [ postcsspxtorem({ rootValue: 37.5, // 设计稿宽度/10 propList: ['*'] }) ] } } }); ``` 2. **性能优化**(引用[1]): - 利用Vite的按需编译特性,减少初始加载资源 - 使用`will-change: transform`提升动画性能 - 采用`backdrop-filter`实现毛玻璃效果(注意浏览器兼容性) 3. **移动端适配**(引用[2][3]): ```html <!-- index.html --> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> ``` ### 完整实现流程图 ```mermaid graph TD A[应用启动] --> B[显示加载动画] B --> C{执行初始化任务} C -->|加载资源| D[异步请求/数据初始化] D --> E{是否完成} E -->|是| F[隐藏加载动画] E -->|否| D F --> G[显示主内容] ``` ### 注意事项 1. **SSR兼容**:如果使用SSR,需要确保加载动画在客户端激活 2. **错误处理**:在初始化过程中添加错误处理逻辑 ```ts const initApp = async () => { try { loading.value?.show(); await Promise.all([fetchUserInfo(), loadConfig()]); } catch (error) { console.error('初始化失败', error); } finally { loading.value?.hide(); appLoaded.value = true; } }; ``` 3. **动画性能**:在移动端使用CSS动画而非JavaScript动画以保证流畅性 > 参考Vite-Vue3-H5模板(引用[2][3])的实现方式,我们采用了REM布局方案并集成了Vant组件库,确保在移动端的兼容性和性能[^2][^3]。 §§相关问题§§ 1. 如何测量Vue3应用的首次内容绘制(FCP)时间? 2. 在Vite项目中如何实现加载动画的按需引入? 3. 如何为Vue3加载动画添加进度条功能? 4. 在移动端H5中,如何优化加载动画在不同设备上的显示效果? 5. 如何结合Pinia管理全局加载状态?</think>下面我将为您详细介绍在 Vue3 + TypeScript + Vite 的 H5 项目中实现页面初始化加载动画的完整方案,结合引用内容中的最佳实践和技术要点。 ### 实现方案 #### 1. 创建加载动画组件 (src/components/Loading.vue) ```vue <template> <teleport to="body"> <transition name="fade"> <div v-show="visible" class="loading-overlay" :class="{ 'dark-mode': darkMode }" > <div class="spinner-container"> <!-- 动态SVG旋转动画 --> <svg class="spinner" viewBox="0 0 50 50"> <circle cx="25" cy="25" r="20" fill="none" :stroke="color" stroke-width="5" ></circle> </svg> <!-- 进度文本 --> <div class="progress-text" v-if="showProgress"> {{ progress }}% </div> <!-- 提示文本 --> <div class="hint-text" v-if="hint"> {{ hint }} </div> </div> </div> </transition> </teleport> </template> <script lang="ts"> import { defineComponent, ref, computed, watch } from 'vue'; export default defineComponent({ name: 'LoadingAnimation', props: { // 控制显示/隐藏 visible: { type: Boolean, default: false }, // 加载进度 (0-100) progress: { type: Number, default: 0 }, // 主题颜色 color: { type: String, default: '#3eaf7c' // Vite 主题绿 }, // 提示文本 hint: { type: String, default: '' }, // 暗黑模式 darkMode: { type: Boolean, default: false } }, setup(props) { // 计算是否显示进度 const showProgress = computed(() => props.progress > 0 && props.progress < 100); // 暴露控制方法 return { showProgress }; } }); </script> <style scoped> /* 覆盖层样式 */ .loading-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.92); display: flex; justify-content: center; align-items: center; z-index: 9999; backdrop-filter: blur(3px); transition: background 0.3s ease; } /* 暗黑模式 */ .dark-mode { background: rgba(0, 0, 0, 0.88); } .spinner-container { text-align: center; } /* 旋转动画 */ .spinner { width: 60px; height: 60px; animation: rotate 1.5s linear infinite; will-change: transform; /* 优化性能 */ } .spinner circle { stroke-linecap: round; stroke-dasharray: 90, 150; stroke-dashoffset: -35; animation: dash 1.5s ease-in-out infinite; } /* 进度文本 */ .progress-text { margin-top: 15px; font-size: 18px; font-weight: bold; color: v-bind('color'); transition: color 0.3s; } /* 提示文本 */ .hint-text { margin-top: 8px; font-size: 14px; color: #666; } .dark-mode .hint-text { color: #aaa; } /* 动画关键帧 */ @keyframes rotate { 100% { transform: rotate(360deg); } } @keyframes dash { 0% { stroke-dasharray: 1, 150; stroke-dashoffset: 0; } 50% { stroke-dasharray: 90, 150; stroke-dashoffset: -35; } 100% { stroke-dasharray: 90, 150; stroke-dashoffset: -124; } } /* 淡入淡出效果 */ .fade-enter-active, .fade-leave-active { transition: opacity 0.3s ease; } .fade-enter-from, .fade-leave-to { opacity: 0; } </style> ``` #### 2. 在 App.vue 中集成加载动画 (src/App.vue) ```vue <template> <div id="app"> <!-- 全局加载动画 --> <LoadingAnimation ref="loader" :visible="isLoading" :progress="loadingProgress" :hint="loadingHint" :dark-mode="isDarkMode" /> <!-- 主内容区域 --> <router-view v-show="!isLoading" /> </div> </template> <script lang="ts"> import { defineComponent, ref, onMounted } from 'vue'; import { useRouter } from 'vue-router'; import LoadingAnimation from '@/components/Loading.vue'; // 模拟资源加载 const loadResources = () => { return new Promise<void>((resolve) => { setTimeout(() => resolve(), 1500); }); }; export default defineComponent({ components: { LoadingAnimation }, setup() { const loader = ref<InstanceType<typeof LoadingAnimation> | null>(null); const isLoading = ref(true); const loadingProgress = ref(0); const loadingHint = ref('正在加载资源...'); const isDarkMode = ref(false); const router = useRouter(); // 更新加载进度 const updateProgress = (progress: number) => { loadingProgress.value = Math.min(100, Math.max(0, progress)); // 根据进度更新提示 if (progress < 30) loadingHint.value = '正在加载资源...'; else if (progress < 70) loadingHint.value = '正在初始化应用...'; else loadingHint.value = '即将完成...'; }; // 模拟加载过程 const simulateLoading = async () => { for (let i = 0; i <= 100; i += 10) { updateProgress(i); await new Promise(r => setTimeout(r, 150)); } await loadResources(); }; // 初始化应用 const initApp = async () => { try { await simulateLoading(); isLoading.value = false; } catch (error) { console.error('初始化失败', error); loadingHint.value = '加载失败,请重试'; // 可添加重试逻辑 } }; // 路由切换时显示加载 router.beforeEach(() => { if (loader.value) { isLoading.value = true; loadingProgress.value = 0; } }); router.afterEach(() => { if (loader.value) { isLoading.value = false; } }); onMounted(initApp); return { loader, isLoading, loadingProgress, loadingHint, isDarkMode }; } }); </script> ``` #### 3. 添加 Vite 配置优化 (vite.config.ts) ```typescript import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import { createHtmlPlugin } from 'vite-plugin-html'; export default defineConfig({ plugins: [ vue(), createHtmlPlugin({ minify: true, inject: { data: { loadingStyle: ` <style> #app-loading { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: #f5f5f5; display: flex; justify-content: center; align-items: center; z-index: 9999; transition: opacity 0.3s; } .app-loading-spinner { width: 40px; height: 40px; border: 3px solid rgba(62, 175, 124, 0.3); border-radius: 50%; border-top-color: #3eaf7c; animation: spin 1s ease-in-out infinite; } @keyframes spin { to { transform: rotate(360deg); } } </style> ` } } }) ], build: { rollupOptions: { output: { // 优化块拆分 manualChunks(id) { if (id.includes('node_modules')) { return 'vendor'; } } } } } }); ``` #### 4. 在 index.html 中添加初始加载样式 ```html <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <title>Vite Vue3 H5</title> <!-- 初始加载样式 --> <%= loadingStyle %> </head> <body> <div id="app-loading"> <div class="app-loading-spinner"></div> </div> <div id="app"></div> <script type="module"> // 隐藏初始加载动画 window.addEventListener('load', () => { const loadingEl = document.getElementById('app-loading'); if (loadingEl) { loadingEl.style.opacity = '0'; setTimeout(() => { loadingEl.style.display = 'none'; }, 300); } }); </script> </body> </html> ``` ### 关键技术解析 1. **双阶段加载动画**: - **HTML/CSS 初始加载**:在 Vue 应用启动前显示的简单动画(防止白屏) - **Vue 组件动画**:应用初始化过程中显示的高级动画(带进度提示) 2. **性能优化**: - 使用 `will-change: transform` 提升动画性能[^1] - 配置 Vite 的 `manualChunks` 优化资源加载[^1] - 使用 `backdrop-filter: blur()` 实现毛玻璃效果 3. **移动端适配**: - 响应式设计:SVG 矢量图形确保高清显示 - REM/VW 布局支持(参考引用[2][3]) ```css /* 在全局样式中添加 */ html { font-size: calc(100vw / 7.5); /* 基于750px设计稿 */ } ``` 4. **主题定制**: - 通过 props 传递颜色主题 - 支持暗黑模式切换 - 使用 CSS 变量动态更新样式 5. **加载状态管理**: - 进度模拟(0-100%) - 动态提示文本 - 路由切换自动触发 ### 最佳实践建议 1. **资源预加载**: ```typescript // 在加载动画期间预加载关键资源 const preloadImages = (images: string[]) => { images.forEach(src => { new Image().src = src; }); }; ``` 2. **性能监控**: ```typescript // 使用 Performance API 监控加载时间 const perfObserver = new PerformanceObserver((list) => { const entries = list.getEntries(); console.log('资源加载时间:', entries); }); perfObserver.observe({ type: 'resource', buffered: true }); ``` 3. **骨架屏集成**(进阶): ```vue <!-- 在加载动画后添加骨架屏 --> <transition name="fade"> <SkeletonScreen v-if="isLoadingContent" /> </transition> ``` 4. **错误处理**: ```typescript // 添加加载失败处理 window.addEventListener('error', () => { loadingHint.value = '资源加载失败,请检查网络'; // 显示重试按钮 }); ``` 5. **动画性能优化**: ```css .spinner { transform: translateZ(0); /* 触发GPU加速 */ } ``` ### 实现效果 1. **加载流程**: - 初始 HTML/CSS 加载动画(立即显示) - Vue 应用启动 - 显示 Vue 加载动画组件 - 资源加载完成 - 隐藏加载动画,显示内容 2. **用户体验优化**: - 平滑的进度反馈 - 上下文相关的提示信息 - 优雅的过渡动画 - 主题一致性 > 参考 Vite-Vue3-H5 模板(引用[2][3])的实现方式,我们采用了 Vant 组件库的响应式设计原则,确保在移动端的兼容性和性能[^2][^3]。同时结合 Vite 的快速启动特性(引用[1]),优化了加载动画的执行效率[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值