یکی دیگر از مباحث مربوط به Routing مربوط به کنترل کردن فرآیند navigation (جابجا شدن بین صفحات) است. در برخی اوقات باید مشخص کنیم که آیا یک کاربر خاص اجازه دارد که URL خاصی را وارد کرده و از آن بازدید کند یا اینکه آیا اجازه دارد از URL خاصی خارج شود؟ مثلا ما در کامپوننت UserDetail.vue هستیم و این کامپوننت دکمه ای به نام Edit User (ویرایش کردن کاربر) دارد. آیا هر کاربری مجاز است که با کلیک روی این دکمه به صفحه ویرایش کاربران برود و بتواند کاربران ما را ویرایش کند؟ قطعا خیر! یا اصلا اگر قرار است کاربر اطلاعات خودش را ویرایش کند حتما باید چک کنیم که Login شده باشد. همچنین می خواهیم خروج کاربر از صفحه UserEdit.vue را نیز کنترل کنیم و من این کار را با یک دکمه ساده انجام می دهم (فایل UserEdit.vue):
<template> <div> <h3>Edit the User</h3> <p>Locale: {{ $route.query.locale }}</p> <p>Analytics: {{ $route.query.q }}</p> <hr /> <button class="btn btn-primary">Confirm</button> <div style="height: 700px"></div> <p id="data">Some extra Data</p> </div> </template>
یعنی کاربر باید در صفحه ویرایش کاربران، تغییرات را تایید (confirm) کند تا بتواند از آن صفحه خارج شود. اگر confirm نکرده باشد، از او می پرسیم که بدون تایید کردن، ویرایش ها اعمال نمی شوند. آیا مطمئن است که می خواهد خارج شود یا نه؟ بنابراین دو قسمت مجزا خواهیم داشت:
با این حساب مجموعا چهار شکل مختلف برای استفاده از gaurd ها داریم. ما در این جلسه با دو مورد اول (وارد شدن به URL های خاص) شروع می کنیم. برای پیاده سازی روش اول باید ابتدا به فایل main.js برویم. ما router خود را در این فایل تعریف کرده و آن را به شیء سراسری Vue پاس داده ایم. حالا باید قبل از پاس دادن آن به Vue بگوییم:
router.beforeEach((to, from, next) => { console.log('global beforeEach'); next(); }); new Vue({ el: '#app', router, render: h => h(App) })
من متد beforeEach را از router صدا زده ام. این متد همانطور که از نامش مشخص است (before یعنی «قبل از» و each یعنی «هر کدام» بنابراین می شود «قبل از هر کدام») قبل از ورود به هر صفحه اجرا خواهد شد. از آنجایی که این تابع روی تک تک صفحات اجرا خواهد شد، فقط می توانیم بررسی های کلی (نه کارهای مخصوص به هر کاموننت) را در آن انجام بدهیم. همچنین از کد بالا مشخص است که آرگومان این متد یک تابع است که سه آرگومان می گیرد:
من درون این تابع کار خاصی نکرده ام بلکه فقط عبارت global beforeEach (یعنی beforeEach سراسری) را log کرده ام تا در کنسول مرورگر آن را ببینیم. اگر حالا به مرورگر رفته و روی هر صفحه ای کلیک کنید یا صفحه مرورگر را refresh کنید، این عبارت را در کنسول خواهید دید. البته در برنامه های واقعی شما باید کدهای واقعی خودتان را درون آن بنویسید. مثلا چک کنید که کاربر برای بازدید از سایت شما (تک تک صفحات) حتما باید login باشد و یک منطق ساده login بودن را پیاده سازی کنید. مشکل این روش اینجاست که متد ما تک تک صفحات را چک می کند اما در بسیاری از اوقات فقط باید مسیر های خاصی را چک کنیم.
فرض کنید می خواهیم فقط از UserDetail.vue محافظت کنیم. برای انجام این کار به فایل routes.js می رویم و خصوصیت beforeEnter را برای UserDetail.vue می نویسیم:
export const routes = [ { path: '', name: 'Home', components: { default: Home, 'header-top': Header } }, { path: '/user', components: { default: User, 'header-bottom': Header }, children: [ { path: '', component: UserStart }, { path: ':id', component: UserDetail, beforeEnter: (to, from, next) => { console.log('inside route setup'); next(); } }, { path: ':id/edit', component: UserEdit, name: 'userEdit' } ] }, { path: '/redirect-me', redirect: { name: 'Home' } }, { path: '*', redirect: '/' } ];
همانطور که می بینید برای path: id که کامپوننت UserDetail را دارد، خصوصیتی به نام beforeEnter (یعنی «قبل از ورود») تعریف کرده ام که یک تابع است. شما می توانید این تابع را در یک فایل دیگر تعریف کرده و سپس مانند بقیه فایل ها در اینجا import کنید اما چون کدهای من کوتاه است تابع را در همین جا نوشته ام. باز هم می گویم که شما باید کدهای واقعی خودتان را به جای console.log قرار بدهید و این فقط یک مثال است. همچنین هیچ وقت یادتان نرود که next را صدا بزنید. حالا باید UserDetail را در مرورگر باز کنیم تا ببینیم log ما نمایش داده می شود یا خیر:
همانطور که می بینید ابتدا global beforeEach و سپس inside route setup اجرا شده اند. در جلسه بعد در مورد روش های سوم (مربوط به ورود به URL) و چهارم (مربوط به خروج از URL) صحبت خواهیم کرد.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.