لارافيل, VueJs / 2024-05-14

سلسة عمليات CRUD بإستخدام Laravel + VueJs مع SPA - الجزء الثالث - إنشاء controller, routes، وجلب البيانات وعرضها في Vue

سلسة عمليات CRUD بإستخدام Laravel + VueJs مع SPA - الجزء الثالث - إنشاء controller, routes، وجلب البيانات وعرضها في Vue

2024-05-14 وقت القراءه : 5 دقائق

في المقالات السابقه تم عرض بيانات بشكل ثابت، في هذا المقال سوف يتم عرض بيانات من خلال الإتصال بـ api لجلب البيانات من قاعدة البيانات.

سنبدأ من Back End وهنا سيتم إستخدام إطار العمل لارافيل.


تحضير لارافيل

إنشاء Post Model

php artisan make:model Post -mf 

تم إستخدام الخيار  -mf من أجل إنشاء:

  • migration file بإسم Posts.
  • Model بإسم Post
  • factory بإسم PostFactory من أجل إدخال بيانات عشوائية في قاعدة البيانات.

للمزيد من الأوامر والخيارات من هنا

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('body');
        $table->timestamps();
    });
}

إضافة fillable

class Post extends Model
{
    use HasFactory;
    protected $fillable = ['title','body'];
}


عمل migrate run

php artisan migrate


إنشاء factory

class PostFactory extends Factory
{
    protected $model = Post::class;

    public function definition()
    {
        return [
            "title" => $this->faker->word(),
            "body" => $this->faker->sentence(),
        ];
    }
}
public function run()
{
    Post::factory(100)->create();
}
php artisan db:seed

للإطلاع أكثر على seeder و factory وتوليد بيانات عشوائية من هنا.


إنشاء PostController

php artisan make:controller Api/PostController -r

إرجاع البيانات من جدول Posts في الدالة index

class PostController extends Controller
{
    public function index()
    {
        return Post::all();
    }
}


تحضير routes

في اللملف rooutes/api.php

Route::get('posts', [PostController::class, 'index']);


لو ذهبنا للرابط  http://www.test.test/api/posts

فإنه سيتم عرض البيانات

{
    "id": 1,
    "title": "nulla",
    "body": "Dolorem magni quo aut doloribus delectus et provident in.",
    "created_at": "2021-08-03T15:53:55.000000Z",
    "updated_at": "2021-08-03T15:53:55.000000Z"
},
{
    "id": 2,
    "title": "porro",
    "body": "Aut dolorem natus eum accusamus dolorem rerum sint.",
    "created_at": "2021-08-03T15:53:55.000000Z",
    "updated_at": "2021-08-03T15:53:55.000000Z"
},


تحضير Vue للإتصال مع الـ api

نذهب للـ component المخصص لعرض المقالات والذي تم إنشاؤه سابقاً، وهو موجود في المسار 

resources/js/components/Posts/index.vue

وبداخل الوسم script نحتاج لعمل ما يلي:

  • export
  • تحديد data property : حيث تحتوي data على المتغيرات التي يتعامل معها html.
  • event للإتصال مع الـ api وذلك من خلال axios.
<script>
export default {
    data(){
        return {
            posts:[]
        }
    },
    mounted() {
        axios.get('/api/posts').then(response=>{
           this.posts=response.data;
        });
    }
}
</script>

في data قمنا بتعريف متغير post ، وفي الدالة mounted تم الإتصال بالـ api والنتائج التي سنحصل عليها سيتم تخزينها في المتغير post الذي قمنا بتعريفة في data.

تعمل mounted مباشرة عند تحميل الصفحة لذلك تم وضع كود الإتصال مع api بإستخدام axios بداخلها.


عرض البيانات

لعرض البيانات يمكن إستخدام v-for directive لعمل loop على posts

<tr v-for="post in posts">
    <td>{{ post.id }}</td>
    <td>{{ post.title }}</td>
    <td>{{ post.body }}</td>
    <td>{{ post.created_at }}</td>
</tr>

وبذلك يتم عرض البيانات

ملاحظة يوجد مجموعه من directive في vuejs مثل v-once، v-show، v-show، v-if, v-else, v-else-if، v-bind, v-on حيث تعتبر هذه الـ directive الأكثر إستخداماً,


التعديل على عرض البيانات

إقتطاع جزء من النص

نلاحظ أن نص المقال طويل، ويفضل أن يتم إقتطاع جزء من النص، حيث يمكن لنا إستخدام دوال جافا سكربت للقيام بذلك

<td>{{ post.body.substring(0,30) }}</td>

إستخدام apiResource

نلاحظ أن حقل التاريخ بحاجة أن يكون أكثر تنسيقا وأكثر قابلية للقراءه، وللقيام بذلك يفضل أن يتم تحضير ذلك في لارافيل، وللقيام بذلك يمكن لنا إستخدام ApiResource

php artisan make:resource PostResource

حيث يتم إنشاء كلاس بإسم PostResource في المسار 

app/Http/Resources/PostResource.php
class PostResource extends JsonResource
{
    public function toArray($request)
    {
        return parent::toArray($request);
    }
}

حيث يمكن هنا تحديد الحقول التي نريد إرجاعها إلى api مع إمكانية عمل تعديلات عليها

class PostResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id'=> $this->id,
            'title'=>$this->title,
            'body'=>$this->body,
            'created_at'=>$this->created_at->toDateString(),
        ];
    }
}

بعد تجهيز PostResource والتعديل على طريقة عرض created_at، يجب إستخدامه في PostController

class PostController extends Controller
{
    public function index()
    {
        return PostResource::collection(Post::all());
    }
}

حيث يتم إرجاع البيانات على شكل collection 

الأن عند زيارتنا للررابط http://www.test.test/api/posts

فإننا سوف نحصل على النتائج التالية

{
"data": [
        {
        "id": 1,
        "title": "nulla",
        "body": "Dolorem magni quo aut doloribus delectus et provident in.",
        "created_at": "2021-08-03"
        },
    ]
}

نلاحظ أن حقل created_at أصبح أسهل للقراءه، وكذلك قامت apiResource بعرض البيانات بداخل data، لذلك نحتاج للقيام بتعديل على دالة mount 

mounted() {
    axios.get('/api/posts').then(response=>{
       this.posts=response.data.data;
    });
}

التعليقات
سيد عبدالله
منذ سنتين

شكرا للمجهود العظيم ملحوظة بسيطة تعديل الاسكربت الخاص بالحصول على البيانات من api وعرضها في view (في ملف index.vue) تعديل السطر من axios.get(\'/api/posts\').then(response=>{ الي axios.get(\'api/posts\').then(response=>{ بحذف فقط / قبل api لكي يصل الي البيانات بشكل صحيح بدون ايرور وشكرا

علي حسين
منذ سنتين

السلام عليكم انا استعمل vue js 3 عندما قمت بتطبيق نفس ما شرحت في المقال حصلت على error (Uncaught ReferenceError: axios is not defined) بحثت في كوكل وحصلت على الحل اضيف import axios from \'axios\' لكل يعمل معي الكود شكرا

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