در قسمت قبل route های خودمان را تعریف کرده و با موفقیت کامپوننت های مختلف آن را بارگذاری کردیم اما در انتهای URL ما علامت هشتگی اضافه شده بود:
تنظیمات پیش فرض vue-router بدین شکل است که از این هشتگ در URL استفاده می کند. اگر با SPA ها آشنا باشید حتما با این استایل از URL ها آشنا هستید و استفاده از آن دلیل خاصی هم دارد. اگر یک URL عادی داشته باشیم و آن را درون مرورگر تایپ کنیم، با زدن کلید enter، درخواستِ باز کردنِ آن URL مستقیما به سرور ارسال می شود که رفتار پیش فرض و طبیعی تمام مرورگر ها و دنیای وب است.
مشکل اینجاست که در برنامه های SPA (برخلاف MPA ها) درخواست ها به سرور ارسال نمی شوند. همانطور که می دانید در SPA ها (برنامه های تک صفحه ای یا single page application) ما فقط بر اساس آدرس موجود در URL یک یا چند کامپوننت خاص را نمایش می دهیم و واقعا چیزی به سرور ارسال نمی شود. بنابراین تنها زمانی درخواست را به سرور ارسال می کنیم که دفعه ی اول بازدید از سایت باشد تا SPA از سرور روی سیستم کاربر دانلود شده و بقیه اش توسط جاوا اسکریپت مدیریت می شود. با این حساب اگر کاربر برای اولین بار آدرس زیر را در مرورگر خود تایپ کند چه اتفاقی می افتد؟
در اینجا (اگر کاربر این آدرس را به صورت دستی در مرورگر وارد کرده و Enter بزند، نه اینکه روی لینکی کلیک کند) قسمت قبل از هشتگ به سرور ارسال می شود و سرور فایل SPA را به شما می دهد. سپس قسمت بعد از هشتگ توسط جاوا اسکریپت و به صورت محلی مدیریت خواهد شد.
بنابراین در نهایت دو راه داریم:
به طور مثال برای سرورهای آپاچی (توجه کنید که با محیط توسعه فعلی کاری نداریم، بلکه در مورد سرورهای واقعی صحبت می کنیم) باید کد زیر را درون مسیر اصلی سایت و فایل 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 های زیر بروید:
سوال: ما که سرور 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).
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.