文章目录
前言
在网页开发中,加载进度条是一种常见的用户体验优化手段,它可以让用户直观地感知页面的加载状态,减少等待的焦虑感。本文将介绍如何使用 Vue.js 实现一个网页加载进度条,并分享一些优化技巧。
一、为什么需要加载进度条?
- 提升用户体验:让用户知道页面正在加载,而不是“卡死”。
- 反馈加载进度:即使无法精确显示进度,也能模拟加载过程。
- 统一视觉风格:替代浏览器默认的加载状态(如旋转图标)。
二、实现思路
核心逻辑
- 监听路由变化:在路由切换时触发进度条开始和结束。
- 模拟进度增长:通过定时器或请求拦截器模拟进度。
- 隐藏进度条:在页面完全加载后隐藏进度条。
技术选型
- 使用 Vue Router 的导航守卫监听路由变化。
- 使用 Vue 3 的响应式数据控制进度条的显示和进度。
- 可选:结合 Axios 拦截器,在请求发起和完成时更新进度。
三、代码实现
1. 创建进度条组件
首先,我们创建一个可复用的进度条组件 ProgressBar.vue
:
<template>
<div v-if="show" class="progress-bar-container">
<div class="progress-bar" :style="{ width: progress + '%' }"></div>
</div>
</template>
<script setup>
defineProps({
show: {
type: Boolean,
default: false
},
progress: {
type: Number,
default: 0
}
});
</script>
<style scoped>
.progress-bar-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 3px;
z-index: 9999;
background-color: #f0f0f0;
}
.progress-bar {
height: 100%;
background-color: #42b983;
transition: width 0.2s ease;
}
</style>
2. 创建进度条逻辑复用函数
我们创建一个可复用的组合式函数 useProgressBar.js
:
import { ref } from 'vue';
export function useProgressBar() {
const showProgress = ref(false);
const progress = ref(0);
const startProgress = () => {
showProgress.value = true;
progress.value = 0;
const interval = setInterval(() => {
progress.value += Math.random() * 10; // 随机增长进度
if (progress.value >= 90) {
clearInterval(interval);
}
}, 200);
};
const finishProgress = () => {
// 模拟延迟,确保进度条能完整显示
setTimeout(() => {
progress.value = 100;
setTimeout(() => {
showProgress.value = false;
}, 300); // 进度条完成后的延迟隐藏
}, 500);
};
return {
showProgress,
progress,
startProgress,
finishProgress
};
}
3. 在主应用中集成
在 App.vue
中使用进度条组件和逻辑:
<template>
<div id="app">
<ProgressBar :show="showProgress" :progress="progress" />
<router-view />
</div>
</template>
<script setup>
import { onMounted } from 'vue';
import { useRouter } from 'vue-router';
import ProgressBar from './components/ProgressBar.vue';
import { useProgressBar } from './composables/useProgressBar';
const router = useRouter();
const { showProgress, progress, startProgress, finishProgress } = useProgressBar();
// 监听路由变化
router.beforeEach(() => {
startProgress();
});
router.afterEach(() => {
finishProgress();
});
// 模拟初始加载
onMounted(() => {
startProgress();
finishProgress();
});
</script>
四、优化技巧
-
结合 Axios 拦截器:
- 在请求发起时增加进度,请求完成时减少进度。
- 示例:
// axios-instance.js
import axios from 'axios';
import { useProgressBar } from './composables/useProgressBar';
const { increaseProgress } = useProgressBar();
const instance = axios.create();
instance.interceptors.request.use(config => {
increaseProgress(10); // 增加 10% 进度
return config;
});
instance.interceptors.response.use(
response => {
increaseProgress(20); // 增加 20% 进度
return response;
},
error => {
increaseProgress(20); // 即使失败也增加进度
return Promise.reject(error);
}
);
export default instance;
-
动态调整进度速度:
- 根据页面复杂度动态调整进度增长速度。
- 例如:首页加载快,进度条增长快;详情页加载慢,进度条增长慢。
-
失败处理:
- 如果加载失败,可以快速完成进度条并显示错误提示。
-
样式优化:
- 添加动画效果(如渐变、闪烁)。
- 支持自定义颜色和高度。
五、完整示例代码
以下是结合路由守卫的完整示例:
1. App.vue
<template>
<div id="app">
<ProgressBar :show="showProgress" :progress="progress" />
<router-view />
</div>
</template>
<script setup>
import { onMounted } from 'vue';
import { useRouter } from 'vue-router';
import ProgressBar from './components/ProgressBar.vue';
import { useProgressBar } from './composables/useProgressBar';
const router = useRouter();
const { showProgress, progress, startProgress, finishProgress } = useProgressBar();
// 监听路由变化
router.beforeEach(() => {
startProgress();
});
router.afterEach(() => {
finishProgress();
});
// 模拟初始加载
onMounted(() => {
startProgress();
finishProgress();
});
</script>
2. useProgressBar.js
import { ref } from 'vue';
export function useProgressBar() {
const showProgress = ref(false);
const progress = ref(0);
const startProgress = () => {
showProgress.value = true;
progress.value = 0;
const interval = setInterval(() => {
progress.value += Math.random() * 10;
if (progress.value >= 90) {
clearInterval(interval);
}
}, 200);
};
const finishProgress = () => {
setTimeout(() => {
progress.value = 100;
setTimeout(() => {
showProgress.value = false;
}, 300);
}, 500);
};
return {
showProgress,
progress,
startProgress,
finishProgress
};
}
六、总结
通过 Vue 3 的 <script setup>
语法糖和组合式 API,我们可以更简洁、更模块化地实现网页加载进度条。这种实现方式不仅代码量少,而且逻辑清晰,易于维护和扩展。希望本文能对你有所帮助!