سنتعرف في هذا المقال، عن مفهوم routes وكيف يمكن تطبيقة في إطار العمل VueJs، ففي التطبيقات يكون هناك component لإضافة المقالات، component لعرض المقالات، حيث يتيح لنا router عرض هذه الـ component دون أن يتم إعاده تحميل الصفحة، من هنا يتطبق لدينا مفهوم SPA حيث أن التطبيق يكون عباره عن صفحة واحده يتم عرض الـ component في هذه الصفحة، دون أن تتم إعاده تحميل للصفحة.
بدلا من إستخدام <a> لعرض الـ component، يجب علينا إستخدام router-link , router-view.
في المشروع الذي نعمل عليه، سيتم إضافة هيدر، بحيث يحتوي على أزرار واحد لإضافة المقالات، والأخر لعرض المقالات، لذلك سيتم عمل إعادة هيكلية للمشروع، وذلك حسب الخطوات التالية:-
إنشاء ملف جديد بإسم App.vue في المسار resources/js/components
<template> <div class="container"> <ul class="nav nav-pills"> <li class="nav-item"> <router-link to="/">Posts List</router-link> </li> <li class="nav-item"> <router-link to="/posts/create">Create Post</router-link> </li> </ul> <div> <router-view></router-view> </div> </div> </template> <script> </script>
جميع الـ component التي سيتم طلبها سيتم عرضها هنا مكان الوسم router-view، وكذلك جميع الـ component سيكون بها nav.
في الملف welcome.blade.php سيتم إزالة جميع الأكواد السابقة وإضافة الوسم app
<body> <div id="app"> <app></app> </div> <script src="{{ mix('js/app.js') }}"></script> </body>
لإستخدام VueRouter نحتاج لتثبيت حزمة vue-router
npm install vue-router
إضافة VueRouter وتفعيله في ملف app.js
import Vue from 'vue'; import VueRouter from 'vue-router' Vue.use(VueRouter)
في المقالات السابقة، قمنا بإعطاء post-index كـ tag لصفحة عرض المقالات من خلال
Vue.component('posts-index', require('./components/Posts/Index.vue').default);
إلا إنه يمكن إستخدام أسماء عوضا عن tag، حيث مكن عمل import للـ component من خلال إستبدال الكود أعلاه بالكود التالي
import PostIndex from './components/Posts/index';
كذلك يجب عمل import للملف app
import App from './components/App'; import PostIndex from './components/Posts/index';
يجب إخبار vue بتحميل الملف الأساسي بالمشروع وهو App.vue وذلك من خلال إضافة باراميتر جديد components إلى Vue instance
const app = new Vue({ el :'#app', components:{ App }, })
إنشاء routes
في ملف app.js يجب القيام بتعريف جميع routes حيث يجب تعريف mode هنا تم إختيار history
const router = new VueRouter({ mode :'history', routes:[ { path:'/', component: PostIndex, }, { path:'/posts/create', component: PostCreate, } ] })
توضيح:
إنشاء component لإضافة المقالات بداخل المسار resources/js/components/Posts/ سيتم إنشاء ملف بإسم create
<template> <div> <form> Post Title:<br/> <input type="text" class="form-control"><br/> Post Text:<br/> <textarea rows="10" class="form-control"></textarea><br/> Category:<br/> <select class="form-control"></select><br/> <button class="btn btn-primary">Save Post</button> </form> </div> </template> <script> </script>
نحتاج لتسجيل هذا الـ component في app.js
import PostCreate from './components/Posts/create';
يجب أن تتم إضافة المتغير router كـ parameter في Vue instance
const app = new Vue({ el :'#app', components:{ App }, router })
Named Routes
كما في لارافيل، أيضا في Vue يمكن إستخدام named routes وذلك من خلال إضافة name لكل object بداخل مصفوفة routes
const router = new VueRouter({ mode :'history', routes:[ { path:'/', component: PostIndex, name:'posts.index' }, { path:'/posts/create', component: PostCreate, name:'posts.create' } ] })
ومن ثم يمكن إستخدام هذه الأسماء في router-link في nav الموجود في الملف app.vue
<template> <div class="container"> <ul class="nav nav-pills"> <li class="nav-item"> <router-link :to="{ name: 'posts.index'}">Posts List</router-link> </li> <li class="nav-item"> <router-link :to="{name:'posts.create'}">Create Post</router-link> </li> </ul> <div> <router-view></router-view> </div> </div> </template> <script></script>
Disable Laravel Routing
لو قمنا بزيارة الرابط http://www.test.test/posts/create مباشرة من المتصفح دون أن نضغط على الزر create post فإننا سوف نحصل على الخطأ 404 NOT FOUND وهذا لأن هذا الرابط لم يتم تعريفه في لارافيل، فهنا يتم طلبه من لارافيل وليس من Vue ولحل هذه المشكله. نذهب للملف web.php ونعدل في route بحيث يقبل أي رابط
Route::get('/{any}', function () { return view('welcome'); })->where('any','.*');
Mark Active Route
بإمكاننا إستخدام active-class="active" ووضعها في الروابط كذلك يجب إضافة exact.
<template> <div class="container"> <ul class="nav nav-pills"> <li class="nav-item"> <router-link active-class="active" exact class="nav-link" :to="{ name: 'posts.index'}">Posts List</router-link> <!-- <a class="nav-link active" aria-current="page" href="#">Active</a>--> </li> <li class="nav-item"> <router-link active-class="active" exact class="nav-link" :to="{name:'posts.create'}">Create Post</router-link> </li> </ul> <div> <router-view></router-view> </div> </div> </template> <script></script>