Chào các bạn, Hôm nay mình xin được chia sẻ với các bạn cách phân quyền router trong VueJS với Vue-Router. Trong bài viết này mình sẽ tập trung vào hướng xử lý logic ngay tại VueRouter, dữ liệu để định nghĩa phân quyền sẽ được các bạn linh hoạt áp dụng vào từng bài tập, dự án nhé. Chính vì vậy, mình sẽ tổ chức dữ liệu mẫu ở dưới ngay trong VueJS để thực hiện.
Phân quyền trong VueJS với Vue-Router
Về cơ bản, phân quyền trong VueJS là cách các bạn tác động tới dữ liệu phân quyền trước khi router được xác định chuyển hướng tới đích. Vậy làm sao để tác động được vào thời điểm này? Chúng ta sẽ sử dụng một khái niệm, đó chính là Navigation Guards trong VueJS. Navigation Guards được chia làm 3 phần chính, 3 phần này sẽ quyết định rằng việc các bạn phân quyền sẽ được định nghĩa ở đâu:
Global Guards – Can thiệp toàn bộ Router
Với Global Guards, các bạn sẽ can thiệp vào toàn bộ các router đã được định nghĩa trong VueRouter. Đồng thời các bạn sẽ có 3 hook tại 3 thời điểm có thể can thiệp vào dữ liệu, chuyển hướng:
const router = new VueRouter({ … });
router.beforeEach((to, from, next) => {
})
router.beforeResolve((to, from, next) => {
})
router.afterEach((to, from) => {
})
Trong đó:
- beforeEach: Sẽ được gọi tới khi mà bất kì router nào của các bạn được người dùng kích hoạt. Tại đây, các bạn sẽ cần 3 tham số đầu vào là to, from và next.
- to: Chứa các thuộc tính của một Router và người dùng hướng đến (dùng chính thuộc tính ở đây để phân quyền).
- from: Chứa các thuộc tính của một Router, cho biết bạn đang ở router nào trước khi bạn chuyển hướng đi.
- next: Đây là một Function bắt buộc các bạn phải gọi để xác định chuyển hướng.
- beforeResolve: Được gọi tới trước khi mà sự điều hướng của chúng ta được xác nhận. Cũng bao gồm 3 tham số như beforeEach
- afterEach: Được gọi khi mà tất cả các logic, xử lý của chúng ta đã xong. Ở afterEach, chúng ta chỉ có 2 tham số là to và from chính vì vậy mà không thể điều hướng sang một router khác ở thời điểm này.
Per-Route Guard – Can thiệp vào từng Router
Nếu như Global Guard viết một nơi can thiệp cho toàn bộ Router, thì Per-Route Guard lại chỉ can thiệp vào cụ thể Router chúng ta định nghĩa:
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
}
}
]
})
Ở đây chúng ta sẽ địn nghĩa thêm beforeEnter trong cấu trúc của Router. Việc định nghĩa này nói chúng ta biết rằng là beforeEnter sẽ được gọi tới trước khi router được chuyển hướng. Tham số truyền vào của beforeEnter bao gồm 3 tham số: to, from và next. Đồng nghĩa với việc các bạn có thể hoàn toàn điều hướng router ở đây.
Component Guards – Can thiệp vào từng component trong VueJS
Đây là mức độ nhỏ nhất cho việc các bạn can thiệp vào Router – đó là Component. Chúng ta sẽ có Options cần lưu ý ở đây:
const Foo = {
template: "...",
beforeRouteEnter (to, from, next) {
},
beforeRouteUpdate (to, from, next) {
},
beforeRouteLeave (to, from, next) {
}
}
Cả beforeRouteEnter, beforeRouteUpdate, beforeRouteLeave đều có 3 tham số là to, from, next. Như vậy chúng ta đều có thể chuyển hướng component tại thời điểm này. Tuy nhiên thì 3 hook này sẽ được gọi ở các thời điểm khác nhau:
- beforeRouteEnter: Được gọi trước khi mà điều hướng được xác nhận. Ở đây bạn không thể truy cập vào con trỏ this của Vue, vì nó được chạy trước khi mà component được khởi tạo.
- beforeRouteUpdate: Được gọi khi mà router đã được thay đổi và chúng ta sẻ dụng lại Component chúng ta định nghĩa ra beforeRouteUpdate.
- beforeRouteLeave: Được gọi trước khi mà chúng ra chuyển hướng ra khỏi component tới một Route khác.
Ứng dụng thực tế phân quyền Router dùng Per-Route Guard
Trên là các phần lý thuyết cơ bản mà chúng ta cần biết và nắm được. Mục đích để trong bất kì một bài toàn nghiệp vụ nào về phân quyền, các bạn cũng có thể biết và tận dụng từng điểm mạnh và tính đúng đắn để sử dụng loại nào cho hợp lý. Ở đây mình sẽ làm một ví dụ nhỏ trong Per-Route Guard để các bạn có thể hiểu các dùng.
Đây là một ví dụ đơn giản về việc phân quyền truy cập vào router ‘/write’. Ở đây mình đã quy định writeRule là những quyền được truy cập và currentRule là quyền hiện tại của người dùng. Tại thời điểm mà gọi đến beforeEnter, mình đã kiểm xem rằng là currentRule có rule nào nằm trong writeRule hay là không. Nếu có thì sẽ đi tiếp tới Router đã chọn, nếu không thì sẽ quy trở về trang chủ.
Một điều lưu ý khi xử lý trong các hàm được gọi đến khi xử lý router là: Khi có tham số next thì bắt buộc trong xử lý phải được gọi đến hàm next và phải đảm bảo rằng nó chỉ được gọi một lần duy nhất. Trong ví dụ trên mình đã dùng if else để làm điều này. Ví dụ dưới đây sẽ là sai nếu các bạn viết như thế này:
Kết luận
Trên đây là một vài hiểu biết của mình về phân quyền Router trong VueJS, hy vọng giúp các bạn nắm được phần nào hướng đi cho bài toán phân quyền. Chúc các bạn học tập và làm việc tốt. Rất mong nhận được sự đóng góp, nhật xét của các bạn.