في المقالات السابقه تم عرض بيانات بشكل ثابت، في هذا المقال سوف يتم عرض بيانات من خلال الإتصال بـ api لجلب البيانات من قاعدة البيانات.
سنبدأ من Back End وهنا سيتم إستخدام إطار العمل لارافيل.
php artisan make:model Post -mf
تم إستخدام الخيار -mf من أجل إنشاء:
للمزيد من الأوامر والخيارات من هنا
public function up() { Schema::create('posts', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('body'); $table->timestamps(); }); }
class Post extends Model { use HasFactory; protected $fillable = ['title','body']; }
php artisan migrate
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 وتوليد بيانات عشوائية من هنا.
php artisan make:controller Api/PostController -r
class PostController extends Controller { public function index() { return Post::all(); } }
في اللملف 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" },
نذهب للـ component المخصص لعرض المقالات والذي تم إنشاؤه سابقاً، وهو موجود في المسار
resources/js/components/Posts/index.vue
وبداخل الوسم script نحتاج لعمل ما يلي:
<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; }); }
السلام عليكم انا استعمل vue js 3 عندما قمت بتطبيق نفس ما شرحت في المقال حصلت على error (Uncaught ReferenceError: axios is not defined) بحثت في كوكل وحصلت على الحل اضيف import axios from \'axios\' لكل يعمل معي الكود شكرا
سيد عبدالله
شكرا للمجهود العظيم ملحوظة بسيطة تعديل الاسكربت الخاص بالحصول على البيانات من api وعرضها في view (في ملف index.vue) تعديل السطر من axios.get(\'/api/posts\').then(response=>{ الي axios.get(\'api/posts\').then(response=>{ بحذف فقط / قبل api لكي يصل الي البيانات بشكل صحيح بدون ايرور وشكرا