Trải Nghiệm Xây Dựng Trang Quản Trị E-Commerce: Tạo Thanh Tiến Trình Hiển Thị Khi Gọi API
Trong dự án e-commerce gần đây của mình, mình đã kết hợp Vue.js với Laravel để xây dựng trang quản trị backend. Một trong những yêu cầu quan trọng là hiển thị thanh tiến trình mỗi khi có cuộc gọi API để lấy dữ liệu, giúp người dùng biết được tiến trình đang diễn ra. Dưới đây là cách mình đã thực hiện điều đó:
Bước 1: Tạo Component ProgressBar.vue
Đầu tiên, chúng ta tạo một component Vue để hiển thị thanh tiến trình theo đường dẫn `resources/js/components/common/ProgressBar.vue` với nội dung sau:
<template>
<div v-if="isActive" class="progress-bar" :style="{ width: `${progress}%` }"></div>
</template>
<script>
export default {
data() {
return {
isActive: false, // Điều khiển việc hiển thị thanh tiến trình
progress: 0, // Phần trăm tiến độ
};
},
methods: {
// Bắt đầu hiển thị thanh tiến trình
start() {
this.isActive = true;
this.progress = 0;
this.increment(); // Gọi hàm tăng tiến độ
},
// Hàm tăng tiến độ
increment() {
if (this.progress < 100) {
this.progress += 1;
setTimeout(this.increment, 200); // Điều chỉnh tốc độ tăng tiến độ (200ms)
}
},
// Hoàn tất tiến trình và ẩn thanh tiến trình
done() {
this.progress = 100;
setTimeout(() => {
this.isActive = false;
}, 300); // Chờ 300ms trước khi ẩn thanh tiến trình
},
},
};
</script>
<style scoped>
.progress-bar {
height: 3px;
background-color: #29d;
position: fixed;
top: 0;
left: 0;
z-index: 9999;
transition: width 0.2s ease-out;
}
</style>
VueGiải thích:
isActive
: Kiểm soát xem thanh tiến trình có hiển thị hay không.progress
: Xác định tiến độ dưới dạng phần trăm.start()
: Bắt đầu quá trình và hiển thị thanh tiến trình.increment()
: Tăng dần tiến độ mỗi 200ms.done()
: Đặt tiến độ về 100% và ẩn thanh sau khi hoàn thành.
Bước 2: Đăng ký Plugin trong Vue
Chúng ta cần đăng ký component này như một plugin để có thể sử dụng nó ở bất kỳ đâu trong ứng dụng.
Trong file app.js của bạn, thêm đoạn code sau:
import Vue from 'vue';
import ProgressBar from './components/common/ProgressBar.vue';
const ProgressPlugin = {
install(Vue) {
// Tạo một instance của ProgressBar
const ProgressBarConstructor = Vue.extend(ProgressBar);
const instance = new ProgressBarConstructor();
document.body.appendChild(instance.$mount().$el); // Gắn component vào DOM
// Gắn instance vào prototype của Vue để sử dụng trong toàn bộ ứng dụng
Vue.prototype.$progress = instance;
},
};
// Đăng ký plugin
Vue.use(ProgressPlugin);
JavaScriptGiải thích:
- Chúng ta tạo một instance của
ProgressBar
và gắn nó vào DOM. - Gắn instance này vào
Vue.prototype.$progress
để có thể truy cập thông quathis.$progress
ở bất cứ đâu trong ứng dụng Vue.
Bước 3: Sử dụng Plugin trong Axios Interceptors hoặc trong component như sau:
Để gọi Vue.prototype.$progress.start()
và Vue.prototype.$progress.done()
trong một component Vue, bạn chỉ cần sử dụng this.$progress.start()
và this.$progress.done()
. Vì plugin đã được gắn vào Vue.prototype
, nó sẽ có sẵn trong tất cả các component thông qua this.$progress
.
Ví dụ:
Giả sử bạn có một component Vue muốn hiển thị thanh tiến trình khi bắt đầu và dừng lại khi một tác vụ (như gọi API) hoàn tất:
<template>
<div>
<button @click="fetchData">Gọi API và hiển thị tiến trình</button>
</div>
</template>
<script>
export default {
methods: {
async fetchData() {
try {
// Bắt đầu tiến trình
this.$progress.start();
// Gọi API giả lập
const response = await axios.get('/api/data');
// Xử lý dữ liệu trả về
console.log(response.data);
// Kết thúc tiến trình sau khi hoàn thành tác vụ
this.$progress.done();
} catch (error) {
// Kết thúc tiến trình nếu có lỗi
this.$progress.done();
console.error('Có lỗi xảy ra:', error);
}
}
}
};
</script>
VueGiải thích:
this.$progress.start()
: Bắt đầu hiển thị thanh tiến trình.this.$progress.done()
: Kết thúc và ẩn thanh tiến trình sau khi tác vụ hoàn thành hoặc có lỗi xảy ra.
Bạn có thể sử dụng hai phương thức này bất kỳ lúc nào cần bắt đầu và kết thúc tiến trình trong component của bạn.