آموزش Vue.js: مدیریت URL با Vue Router — بخش دهم و پایانی

۳۹۳ بازدید
آخرین به‌روزرسانی: ۱۴ شهریور ۱۴۰۲
زمان مطالعه: ۸ دقیقه
آموزش Vue.js: مدیریت URL با Vue Router — بخش دهم و پایانی

در وب‌اپلیکیشن‌های جاوا اسکریپت منظور از مسیر بخشی است که نمای نمایش یافته کنونی را با محتوای نوار آدرس مرورگر همگام‌سازی می‌کند. به بیان دیگر بخشی است که تغییرات URL را در زمان کلیک کردن روی چیزی در صفحه بر عهده دارد و به نمایش نمای مناسب در زمان کلیک روی یک URL خاص کمک می‌کند. در این مقاله که آخرین بخش از این سری مقالات است به توضیح روش مدیریت URL با Vue Router می‌پردازیم. برای مطالعه بخش قبلی این سری مقالات روی لینک زیر کلیک کنید:

به طور سنتی وب بر مبنای URL-ها ساخته شده است. زمانی که روی یک URL خاص کلیک می‌کنید، صفحه مربوطه نمایش پیدا می‌کند. با معرفی اپلیکیشن‌هایی که درون مرورگر اجرا می‌شوند و چیزی که کاربر می‌بیند را تغییر می‌دهند، بسیاری از اپلیکیشن‌ها این تعامل را کنار گذاشتند و شما باید URL را به صورت دستی با API History مرورگر به‌روزرسانی کنید. بدین ترتیب زمانی که می‌خواهید URL-ها را با View-ها در اپلیکیشن همگام‌سازی کند به «مسیریاب» (Router) نیاز دارید.

کتابخانه Vue Router روشی برای اجرای کارهای فوق در اپلیکیشن‌های Vue محسوب می‌شود. Vue استفاده از این کتابخانه را الزام نکرده است. می‌توانید از هر کتابخانه مسیریابی دیگری که می‌خواهید نیز استفاده کنید و یا یکپارچه‌سازی History API خاص خود را بسازید، اما مزیت استفاده از Vue Router در رسمی بودن آن است.

این بدان معنی است که این کتابخانه از سوی همان افرادی نگهداری می‌شود که خود Vue را نوشته‌اند و از این رو یکپارچگی بهتری با این فریمورک دارد و تضمین می‌کند که در آینده نیز هر اتفاقی بیفتد، همواره با این فریمورک سازگار خواهد بود.

نصب

Vue Router از طریق NPM در پکیجی به نام vue-router ارائه شده است.

اگر از Vue از طریق تگ اسکریپت استفاده می‌کنید، می‌توانید به روش زیر vue-router را در پروژه خود بگنجانید:

1<script src="https://unpkg.com/vue-router"></script>

«UNPKG» (+) یک ابزار بسیار کارآمد است که ارائه پکیج‌های npm در مرورگر را با یک لینک ساده به راحتی انجام می‌دهد. اگر از Vue CLI استفاده می‌کنید، آن را با دستور زیر نصب کنید:

npm install vue-router

زمانی که vue-router نصب شد و از طریق استفاده از تگ اسکریپت یا Vue CLI در دسترس قرار گرفت می‌توانید آن را در اپلیکیشن خود ایمپورت کنید. این کتابخانه را پس از vue ایمپورت کرده و با فراخوانی Vue.use(VueRouter) آن را درون اپلیکیشن نصب کنید:

1import Vue from 'vue'
2import VueRouter from 'vue-router'
3
4Vue.use(VueRouter)

پس از فراخوانی ()Vue.use شیء مسیریاب در هر کامپوننت اپلیکیشن که به این اشیا دسترسی دارند، ارسال می‌شود:

  • this.$router شیء مسیریاب است.
  • this.$route شیء مسیر است.

شیء مسیریاب

شیء مسیریاب که پس از نصب Vue Router در کامپوننت Root ویو از طریق this.$router در هر کامپوننت در دسترس ما است، قابلیت‌های زیبای زیادی دارد. برای نمونه می‌توانیم کاری کنیم که اپلیکیشن با استفاده از دستورهای زیر به مسیر جدیدی بروید:

  • this.$router.push()
  • this.$router.replace()
  • this.$router.go()

این دستورها شبیه متدهای pushState ،replaceState و go در pushState ،replaceState and go هستند.

  • ()push برای رفتن به مسیر جدید استفاده می‌شود و یک آیتم جدید به تاریخچه مرورگر اضافه می‌کند.
  • ()replace نیز همان است به جز این که یک حالت جدید به تاریخچه ارسال نمی‌کند.

در ادامه مثال‌هایی از این دستورها ارائه شده است:

1this.$router.push('about') //named route, see later
2this.$router.push({ path: 'about' })
3this.$router.push({ path: 'post', query: { post_slug: 'hello-world' } }) //using query parameters (post?post_slug=hello-world)
4this.$router.replace({ path: 'about' })

()go به پس و پیش می‌رود و عددی قبول می‌کند که می‌تواند مثبت یا منفی باشد تا بتوانیم در تاریخچه به عقب حرکت کنیم:

1this.$router.go(-1) //go back 1 step
2this.$router.go(1) //go forward 1 step

تعریف کردن مسیرها

ما در این مثال از کامپوننت تک فایلی (SFC) در Vue استفاده می‌کنیم. در قالب از یک تگ nav که دارای سه کامپوننت router-link است استفاده می‌کنیم. هر کدام از این‌ها به ترتیب دارای برچسب‌های Home ،Login و About هستند. یک URL از طریق خصوصیت go اختصاص یافته است. کامپوننت router-view جایی است که Vue Router محتوایی که با URL جاری مطابقت دارد قرار می‌دهد.

1<template>
2  <div id="app">
3    <nav>
4      <router-link to="/">Home</router-link>
5      <router-link to="/login">Login</router-link>
6      <router-link to="/about">About</router-link>
7    </nav>
8    <router-view></router-view>
9  </div>
10</template>

کامپوننت router-link به طور پیش‌فرض یک تگ a را رندر می‌کند. هر بار که مسیر تغییر می‌یابد، چه این تغییر از طریق یک کلیک روی لینک باشد و چه با تغییر دادن URL باشد، یک کلاس router-link-active به عنصری که به مسیر فعال اشاره می‌کند، اضافه می‌شود و امکان استایل‌بندی آن را فراهم می‌سازد. در بخش جاوا اسکریپت ابتدا مسیریاب را قرار داده و نصب می‌کنیم و سپس 3 کامپوننت route تعریف می‌کنیم. این کامپوننت‌ها را به مقداردهی اولیه شیء router ارسال می‌کنیم و این شیء را نیز به وهله root ویو می‌فرستیم.

کد آن چنین است:

1<script>
2import Vue from 'vue'
3import VueRouter from 'vue-router'
4
5Vue.use(VueRouter)
6
7const Home  = {
8  template: '<div>Home</div>'
9}
10
11const Login = {
12  template: '<div>Login</div>'
13}
14
15const About = {
16  template: '<div>About</div>'
17}
18
19const router = new VueRouter({
20  routes: [
21    { path: '/', component: Home },
22    { path: '/login', component: Login },
23    { path: '/about', component: About }
24  ]
25})
26
27new Vue({
28  router
29}).$mount('#app')
30</script>

به طور معمول در یک اپلیکیشن Vue اپلیکیشن root با استفاده از دستور زیر وهله‌سازی شده و نصب می‌شود:

1new Vue({
2  render: h => h(App)
3}).$mount('#app')

زمانی که از Vue Router استفاده می‌کنیم، دیگر مشخصه render را ارسال نمی‌کنیم، بلکه به جای آن از router بهره می‌گیریم. ساختار مورد استفاده در مثال فوق چنین است:

1new Vue({
2  router
3}).$mount('#app')

که خلاصه شده کد زیر است:

1new Vue({
2  router: router
3}).$mount('#app')

در مثال فوق می‌بینیم که یک آرایه routes به سازنده VueRouter ارسال شده است. هر مسیر در این آرایه دارای پارامترهای path و component است. اگر یک پارامتر name نیز ارسال کرده باشید، دارای یک مسیر نامدار خواهید بود.

استفاده از مسیرهای نامدار برای ارسال پارامترها به متدهای push و replace مسیریاب

اگر به خاطر داشته باشید در بخش قبل از شیء Router برای ارسال یک حالت جدید استفاده کردیم:

1this.$router.push({ path: 'about' })

در مسیر نامدار می‌توانیم پارامترها را برای مسیر جدید ارسال کنید:

1this.$router.push({ name: 'post', params: { post_slug: 'hello-world' } })

همین واقعیت در مورد ()replace نیز صدق می‌کند:

1this.$router.replace({ name: 'post', params: { post_slug: 'hello-world' } })

اپلیکیشن در این حالت کامپوننت مسیر را که با URL ارسالی به لینک مطابقت دارد، رندر خواهد کرد. کامپوننت مسیر جدید که URL را مدیریت می‌کند، وهله‌سازی شده و گاردهای آن فراخوانی می‌شود و کامپوننت مسیر قدیمی تخریب خواهد شد.

گاردهای مسیر

از آنجا که در بخش قبل به گاردها اشاره کردیم، لازم است که کمی در مورد آن توضیح دهیم. گاردها را می‌توان قلاب‌ها یا میان‌افزار چرخه عمر تصور کرد که تابع‌هایی هستند که در زمان‌های خاص در طی اجرای اپلیکیشن فراخوانی می‌شوند. بدین ترتیب می‌توان در اجرای مسیر پرش‌هایی داشت و ترتیب اجرای آن را تغییر داد یا درخواست را هدایت مجدد کرده و لغو نمود.

از گاردهای سراسری می‌توان با افزودن callback به مشخصه ()beforeEach و ()afterEach مسیریاب استفاده کرد.

  • ()beforeEach پیش از تأیید ناوبری فراخوانی می‌شود.
  • ()beforeResolve زمانی فراخوانی می‌شود که beforeEach اجرا شود و همه گاردهای کامپوننت‌های beforeRouterEnter و beforeRouteUpdate فراخوانی شوند، اما اجرای آن پیش از تأیید ناوبری است.
  • ()afterEach پس از تأیید ناوبری اجرا می‌شود.

منظور از تأیید ناوبری در بندهای فوق را کمی بعدتر توضیح خواهیم داد. در حال حاضر آن را می‌توانید به عنوان اجازه رفتن اپلیکیشن به یک مسیر فرض کنید.

کاربرد آن چنین است:

1this.$router.beforeEach((to, from, next) => {
2  // ...
3})
1this.$router.afterEach((to, from) => {
2  // ...
3})

مقادیر to و from نماینده اشیای مسیر هستند و نشان می‌دهند که از to آمده و به from می‌رویم. beforeEach یک پارامتر next دیگر هم دارد که در صورت فراخوانی با پارامتر false ظاهر می‌شود و ناوبری را مسدود می‌کند و از تأیید آن جلوگیری می‌کند. اگر با میان‌افزارهای Node آشنا باشید، می‌دانید که next()‎ نیز باید همواره فراخوانی شود، چون در غیر این صورت اجرا متوقف می‌شود.

کامپوننت‌های تک مسیری نیز گارد دارند:

  • beforeRouteEnter(from, to, next) پیش از تغییر مسیر جاری فراخوانی می‌شود.
  • beforeRouteUpdate(from, to, next) زمانی فراخوانی می‌شود که مسیر تغییر یابد، اما کامپوننتی که آن را مدیریت می‌کند، همچنان همان باشد. (این کار از طریق مسیریابی دینامیک که در بخش بعدی توضیح داده‌ایم امکان‌پذیر است)
  • beforeRouteLeave(from, to, next) زمانی فراخوانی می‌شود که از مکان فعال برویم.

در بخش قبلی از ناوبری صحبت کردیم، Vue Router برای تعیین این که ناوبری به یک مسیر تأیید شده یا نه بررسی‌های زیر را انجام می‌دهد:

  • گارد beforeRouteLeave را در کامپوننت (های) جاری فرا می‌خواند.
  • گارد ()beforeEach مسیر را فرا می‌خواند.
  • ()beforeRouteUpdate را در هر کامپوننت که باید مجدداً استفاده شود (در صورت وجود) فرا می‌خواند.
  • گارد ()beforeEnter را روی شیء مسیر فرا می‌خواند.
  • ()beforeRouterEnter را در کامپوننتی که باید واردش شویم فرا می‌خواند.
  • گارد ()beforeResolve مسیر را فرا می‌خواند.
  • اگر همه موارد فوق برقرار باشند، ناوبری تأیید می‌شود.
  • گارد ()afterEach مسیر را فرا می‌خواند.

می‌توانید از گاردهای خاص مسیر (beforeRouteEnter و beforeRouteUpdate در مورد مسیریابی دینامیک) به عنوان قلاب‌های چرخه عمر استفاده کنید. بدین ترتیب می‌توانید برای نمونه درخواست‌های واکشی داده را آغاز کنید.

مسیریابی دینامیک

مثال فوق یک view متفاوت را بر مبنای URL نمایش می‌دهد و مسیرهای /، login/ و about/ را مدیریت می‌کند.

در اغلب موارد نیاز داریم که مسیرهای دینامیک را مدیریت کنیم. این کار مانند داشتن پست‌های زیادی در مسیر /post/ است که هر کدام نامی مخصوص خود دارند:

  • /post/first
  • /post/another-post
  • /post/hello-world

این وضعیت با استفاده از قطعه دینامیک میسر خواهد بود. این موارد قطعه‌های استاتیک هستند:

1const router = new VueRouter({
2  routes: [
3    { path: '/', component: Home },
4    { path: '/login', component: Login },
5    { path: '/about', component: About }
6  ]
7})

در ادامه یک قطعه دینامیک برای مدیریت پست‌های بلاگ اضافه می‌کنیم:

1const router = new VueRouter({
2  routes: [
3    { path: '/', component: Home },
4    { path: '/post/:post_slug', component: Post },
5    { path: '/login', component: Login },
6    { path: '/about', component: About }
7  ]
8})

به استفاده از ساختار :post_slug توجه کنید. این بدان معنی است که می‌توانید از هر رشته‌ای استفاده کنید و این رشته به یک placeholder به نام post_slug نگاشت می‌شود. البته شما محدود به استفاده از این ساختار نیستید. Vue از این کتابخانه (+) برای تحلیل مسیرهای دینامیک استفاده می‌کند و می‌توانید از «عبارت‌های منظم» (Regular Expressions) نیز استفاده کنید.

اکنون درون کامپوننت مسیر Post می‌توانیم با استفاده از route$ به مسیر ارجاع بدهیم و با بهره‌گیری از route.params.post_slug$ نیز به نام پست اشاره می‌کنیم:

1const Post = {
2  template: '<div>Post: {{ $route.params.post_slug }}</div>'
3}

از این پارامتر برای بارگذاری محتوا از بک‌اند نیز می‌توان استفاده کرد. شما می‌توانید به هر تعداد که دوست دارید، قطعه‌های دینامیک در یک URL داشته باشید:

/post/:author/:post_slug

اگر به خاطر داشته باشید در بخش قبل در مورد اتفاقاتی که در زمان ناوبری کاربر به یک مسیر جدید می‌افتد صحبت کردیم. در مورد مسیرهای دینامیک اتفاقاتی که می‌افتند کمی متفاوت هستند.

Vue در این مورد به روش کارآمدتری عمل می‌کند و به جای تخریب کامپوننت مسیر جاری و وهله‌سازی مجدد از آن، از وهله جاری استفاده مجدد می‌کند. زمانی که این اتفاق بیفتد، Vue رویداد چرخه عمر beforeRouteUpdate را فراخوانی می‌کند. در اینجا می‌توان هر عملیاتی که لازم است را اجرا کرد:

1const Post = {
2  template: '<div>Post: {{ $route.params.post_slug }}</div>'
3  beforeRouteUpdate(to, from, next) {
4    console.log(`Updating slug from ${from} to ${to}`)
5    next() //make sure you always call next()
6  }
7}

استفاده از props

در مثال‌های فوق از *.route.params$ برای دسترسی به داده‌های مسیر استفاده کردیم. هیچ کامپوننتی نباید با مسیریاب تزویج سفت و سختی داشته باشد و به جای آن باید از props استفاده کرد:

1const Post = {
2  props: ['post_slug'],
3  template: '<div>Post: {{ post_slug }}</div>'
4}
5
6const router = new VueRouter({
7  routes: [
8    { path: '/post/:post_slug', component: Post, props: true }
9  ]
10})

به شیوه ارسال props: true به شیء route برای فعال‌سازی این کارکرد توجه کنید.

مسیرهای تودرتو

پیش‌تر اشاره کردیم که می‌توانیم به تعداد دلخواهی قطعه‌های دینامیک در یک URL مانند زیر داشته باشیم:

/post/:author/:post_slug

بنابراین یک کامپوننت Author داریم که مسئولیت مراقبت از قطعه دینامیک اول را بر عهده می‌گیرد:

1<template>
2  <div id="app">
3    <router-view></router-view>
4  </div>
5</template>
6
7<script>
8import Vue from 'vue'
9import VueRouter from 'vue-router'
10
11Vue.use(VueRouter)
12
13const Author  = {
14  template: '<div>Author: {{ $route.params.author}}</div>'
15}
16
17const router = new VueRouter({
18  routes: [
19    { path: '/post/:author', component: Author }
20  ]
21})
22
23new Vue({
24  router
25}).$mount('#app')
26</script>

می‌توانیم یک وهله کامپوننت router-view دوم را درون قالب Author قرار دهیم:

1const Author  = {
2  template: '<div>Author: {{ $route.params.author}}<router-view></router-view></div>'
3}

کامپوننت Post را اضافه می‌کنیم:

1const Post = {
2  template: '<div>Post: {{ $route.params.post_slug }}</div>'
3}

و سپس مسیر دینامیک درونی را در پیکربندی Vue Router تزریق می‌کنیم:

1const router = new VueRouter({
2  routes: [{
3    path: '/post/:author',
4    component: Author,
5    children: [
6      path: ':post_slug',
7      component: Post
8    ]
9  }]
10})

به این ترتیب به پایان این مقاله از سری مقالات آموزش جامع Vue.js می‌رسیم. این آخرین مقاله از این سری است و بنابراین این سری راهنماهای آموزشی نیز به آخر می‌رسند. امیدواریم این راهنمای جامع مورد توجه شما قرار گرفته باشد.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۵ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
freecodecamp
۴ دیدگاه برای «آموزش Vue.js: مدیریت URL با Vue Router — بخش دهم و پایانی»

عالی اگر برای هر قسمت یک فیلم هم می شد گذاشت خوب بود با مثال

درود آموزش کاملی بود ولی من یه وبسایت با ویو روتر درست کردم آپلود کردم ولی وقتی ادرس یه روتر رو توی تب مرورگر کپی میکنم صفحه ارور باز میشه
ممنون میشم کمک کنید

آموزش خوبی بود ، ممنون از پست خوبتون
فقط اگه یه مثال کامل میزدی که کامل تفهیم بشه میتونست بهتر هم بشه.
با تشکر

جالب بود.
همه قسمت ها رو خوندم
ساده توضیح داده بودید و بسیار کارآمد.
تشکر

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *