لارافيل, VueJs / 2024-12-21

سلسة عمليات CRUD بإستخدام Laravel + VueJs مع SPA - الجزء السابع - Vue Router

سلسة عمليات CRUD بإستخدام Laravel + VueJs مع SPA - الجزء السابع - Vue Router

2024-12-21 وقت القراءه : 4 دقائق

سنتعرف في هذا المقال، عن مفهوم routes وكيف يمكن تطبيقة في إطار العمل VueJs، ففي التطبيقات يكون هناك component لإضافة المقالات، component لعرض المقالات، حيث يتيح لنا router عرض هذه الـ component دون أن يتم إعاده تحميل الصفحة، من هنا يتطبق لدينا مفهوم SPA حيث أن التطبيق يكون عباره عن صفحة واحده يتم عرض الـ component في هذه الصفحة، دون أن تتم إعاده تحميل للصفحة.

بدلا من إستخدام <a> لعرض الـ component، يجب علينا إستخدام router-link , router-view.

  • router-link فعند الضغط عليه، يتم عمل fire في java script لعرض الـ component المرتبط بهذا الحدث.
  • router-view هو المكان الذي سيتم عرض محتويات الـ component بداخلة.


في المشروع الذي نعمل عليه، سيتم إضافة هيدر، بحيث يحتوي على أزرار واحد لإضافة المقالات، والأخر لعرض المقالات، لذلك سيتم عمل إعادة هيكلية للمشروع، وذلك حسب الخطوات التالية:-

إنشاء ملف جديد بإسم 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,
        }
    ]
})

توضيح:

  • تم عمل instance من vueRouter.
  • بداخل vueRouter يجب تحديد mode و routes
  • routes تتكون من مصفوفة بحيث تحتوي على object لكل route وهما path وهو الرابط، ويتم وضعه في router-link و component وهو الإسم الذي تم إعتماده عند عمل import للـ component


إنشاء 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>



إضافة تعليق
Loading...