آشنایی با Routing Modes و اضافه‌کردن لینک‌ها

Learn about Routing Modes and Adding Links

25 آبان 1399
Vue.JS 2: آشنایی با routing modes و اضافه کردن لینک ها - قسمت 77

در قسمت قبل route های خودمان را تعریف کرده و با موفقیت کامپوننت های مختلف آن را بارگذاری کردیم اما در انتهای URL ما علامت هشتگی اضافه شده بود:

http://localhost:8080/#/

http://localhost:8080/#/user

تنظیمات پیش فرض vue-router بدین شکل است که از این هشتگ در URL استفاده می کند. اگر با SPA ها آشنا باشید حتما با این استایل از URL ها آشنا هستید و استفاده از آن دلیل خاصی هم دارد. اگر یک URL عادی داشته باشیم و آن را درون مرورگر تایپ کنیم، با زدن کلید enter، درخواستِ باز کردنِ آن URL مستقیما به سرور ارسال می شود که رفتار پیش فرض و طبیعی تمام مرورگر ها و دنیای وب است.

مشکل اینجاست که در برنامه های SPA (برخلاف MPA ها) درخواست ها به سرور ارسال نمی شوند. همانطور که می دانید در SPA ها (برنامه های تک صفحه ای یا single page application) ما فقط بر اساس آدرس موجود در URL یک یا چند کامپوننت خاص را نمایش می دهیم و واقعا چیزی به سرور ارسال نمی شود. بنابراین تنها زمانی درخواست را به سرور ارسال می کنیم که دفعه ی اول بازدید از سایت باشد تا SPA از سرور روی سیستم کاربر دانلود شده و بقیه اش توسط جاوا اسکریپت مدیریت می شود. با این حساب اگر کاربر برای اولین بار آدرس زیر را در مرورگر خود تایپ کند چه اتفاقی می افتد؟

http://localhost:8080/#/user

در اینجا (اگر کاربر این آدرس را به صورت دستی در مرورگر وارد کرده و Enter بزند، نه اینکه روی لینکی کلیک کند) قسمت قبل از هشتگ به سرور ارسال می شود و سرور فایل SPA را به شما می دهد. سپس قسمت بعد از هشتگ توسط جاوا اسکریپت و به صورت محلی مدیریت خواهد شد.

بنابراین در نهایت دو راه داریم:

  • یا از همین استایل هشتگ استفاده کنید و نیازی به انجام کار های دیگر نیست.
  • یا از حالت عادی URL ها استفاده کنید (در ادامه می بینید) اما باید سرور خود را طوری تنظیم کنید که با هر درخواست فایل html برگردانده شود نه چیز دیگر، حتی در درخواست های 404. این تنظیمات بستگی به سرور شما دارد و می توانید با جست و جوی ساده تنظیمات آن را پیدا کنید.

به طور مثال برای سرورهای آپاچی (توجه کنید که با محیط توسعه فعلی کاری نداریم، بلکه در مورد سرورهای واقعی صحبت می کنیم) باید کد زیر را درون مسیر اصلی سایت و فایل index.html (در فایل htaccess.) اضافه کنید:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

یا برای سرورهای nginx فایل پیکربندی سرور را پیدا کرده و می گوییم:

location / {
  try_files $uri $uri/ /index.html;
}

برای اطلاعات به آدرس زیر از documentation رسمی Vue Router مراجعه کنید:

https://router.vuejs.org/guide/essentials/history-mode.html#example-server-configurations

پس از آنکه سرور واقعی خود را به شکل صحیح تنظیم کردید به فایل main.js رفته و می گوییم:

const router = new VueRouter({
  routes,
  mode: 'history'
});

نام حالت بدون هشتگ history و نام حالت پیش فرض و با هشتگ، hash می باشد. حالا اگر به مرورگر بروید، می بینید که می توانید به URL های زیر بروید:

http://localhost:8080/

http://localhost:8080/user

سوال: ما که سرور webpack را تنظیم نکرده ایم و اصلا آن را ویرایش نکرده ایم! چطور حالت history کار می کند؟

پاسخ: ما از Vue-Cli استفاده می کنیم و در آن سرور webpack طوری تنظیم شده است که همیشه فایل index.html را برگرداند و به URL کاری نداشته باشد. بنابراین سرور ما از قبل تنظیم شده است و نباید هیچ چیز را در محیط توسعه ی خود عوض کنید (به جز فایل main.js و حالت history). مسائل ذکر شده در بالا فقط برای سرورهای واقعی است.

ساخت لینک برای جابجایی بین کامپوننت ها

برای اینکه هر بار آدرس را به صورت دستی درون مرورگر وارد نکنیم می توانیم وارد پوشه ی components شده و فایلی به نام Header.vue بسازیم. محتویات این فایل به شکل زیر است:

<template>
  <ul class="nav nav-pills">
    <li role="presentation">
      <router-link to="/">Home</router-link>
    </li>
    <li role="presentation">
      <router-link to="/user">User</router-link>
    </li>
  </ul>
</template>

کامپوننت router-link در واقع معادل <a> یا لینک های عادی است اما لینک های عادی درخواست را به سرور ارسال می کنند و ما نمی خواهیم چنین اتفاقی بیفتد بنابراین از router-link استفاده کرده ایم. همچنین خصوصیت to یک رشته می گیرد که سپس به انتهای URL شما پیوست می شود بنابراین user/ یعنی example.com/user. در نهایت کلاس هایی که به این عناصر داده شده است همگی کلاس های بوت استرپ هستند و به Vue ربطی ندارند. در مرحله ی بعد باید وارد App.vue شویم و این کامپوننت را در آن وارد کنیم:

<script>
import Header from "./components/Header.vue";
export default {
  components: {
    appHeader: Header
  }
};
</script>

در نهایت از آن در template همین فایل (App.vue) استفاده می کنیم:

<div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3">
<h1>Routing</h1>
<hr />
<app-header></app-header>
<router-view></router-view>
</div>

حالا اگر به مرورگر برویم و این دکمه ها را تست کنیم، می بینید که همه چیز به درستی کار می کند و می توانیم بین دو کامپوننت جا به جا شویم. همچنین اگر این دکمه ها را inspect کنیم (روی آن کلیک راست کرده و inspect element را بزنیم یا از dev tools به سورس کد صفحه نگاه کنیم) متوجه خواهیم شد که router-link در نهایت تبدیل به تگ <a> می شوند و اثری از router-link نیست.

حتما متوجه شده اید که این تگ ها بدون refresh کردن صفحه کار می کنند. دلیل آن هم این است که این <a> ها دارای کلاس router-link هستند و در پشت صحنه یک event listener در حال گوش دادن به آن ها است تا رفتار پیش فرضشان را متوقف کند (preventDefault).

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

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.