لارافيل, VueJs / 2024-11-23

سلسة عمليات CRUD بإستخدام Laravel + VueJs مع SPA - الجزء الحادي عشر - حذف البيانات

سلسة عمليات CRUD بإستخدام Laravel + VueJs مع SPA - الجزء الحادي عشر - حذف البيانات

2024-11-23 وقت القراءه : 5 دقائق

في هذا المقال سوف نتحدث عن عملية الحذف بإستخدام VueJs و Laravel وللقيام بذلك


تحضير Front End بإستخدام Vue

إضافة زر للحذف

في الـ component المخصص لعرض البيانات والموجود في المسار resources/js/components/Posts/index.vue نضيف زر للحذف، مع حدث click حيث يتم تنفيذ دالة delete_post مع إرسال id الـ post

<td>
    <button @click="delete_post(post.id)" class="btn btn-danger">Delete</button>
</td>


دالة الحذف

في داخل الدالة mounted ننشئ الدالة post_delete وهي تستقبل الـ id المراد حذفة

delete_post(id) {
    swal({
        title: "Are Your Shure You Want to Delete The Post ?",
        icon: "warning",
        buttons: ["No", "Yes"],
        dangerMode: true,
    })
        .then((willDelete) => {
            if (willDelete) {
                axios.delete('/api/posts/' + id).then(response => {
                    swal("Post Deleted Successfully");
                    this.getResults()
                })
            } else {
                swal("Post Not Deleted");
            }
        }).catch(error => {
        swal({
            icon: 'error',
            title: 'Error Happened'
        });
    });
}

توضيح

  • عند تنفيذ الدالة، ستظهر رسالة تأكيد للمستخدم، إن كان يريد إكمال الحذف أم لا.
  • عند الضغط على تأكيد سيتم الإتصال مع الـ api من خلال axios من نوع delete، مع إرسال ال id المراد حذفة.
  • بعد الحذف ستظهر رسالة بنجاح الحذف، ومن ثم سيتم تنفيذ دالة جلب البيانات.
  • إذا ضغط المستخدم على إلغاء الحذف ستظهر رسالة post not deleted مع الغاء الحذف.
  • اذا كان هناك خطأ ستظهر رسالة Error Happened.


تحضير Back End من خلال Laravel

نحتاج لإنشاء دالة destroy حيث تأخذ Post المراد حذفة، وبعد الحذف لا يتم إرجاع شيئ.

public function destroy(Post $post)
{
    $post->delete();
    return response()->noContent();
}



الكود بالكامل

<template>
    <div class="container">
        <br/>
        <select v-model="category_id" class="form-control">
            <option value="">--Choose Category--</option>
            <option v-for="category in categories" :value="category.id">
                {{ category.name }}
            </option>
        </select>
        <br/>
        <table class="table">
            <thead>
            <tr>
                <th scope="col">
                    <a href="#" @click.prevent="change_sort('id')">id</a>
                    <span
                        :class="this.sort_field === 'id' && this.sort_direction === 'asc' ? 'text-dark' : 'text-black-50'">&uarr;</span>
                    <span
                        :class="this.sort_field === 'id' && this.sort_direction === 'desc' ? 'text-dark' : 'text-black-50'">&darr;</span>
                </th>
                <th scope="col">
                    <a href="#" @click.prevent="change_sort('title')">title</a>
                    <span
                        :class="this.sort_field === 'title' && this.sort_direction === 'asc' ? 'text-dark' : 'text-black-50'">&uarr;</span>
                    <span
                        :class="this.sort_field === 'title' && this.sort_direction === 'desc' ? 'text-dark' : 'text-black-50'">&darr;</span>
                </th>
                <th scope="col">
                    <a href="#" @click.prevent="change_sort('body')">body</a>
                    <span
                        :class="this.sort_field === 'body' && this.sort_direction === 'asc' ? 'text-dark' : 'text-black-50'">&uarr;</span>
                    <span
                        :class="this.sort_field === 'body' && this.sort_direction === 'desc' ? 'text-dark' : 'text-black-50'">&darr;</span>
                </th>
                <th scope="col">
                    <a href="#" @click.prevent="change_sort('created_at')">created_at</a>
                    <span
                        :class="this.sort_field === 'created_at' && this.sort_direction === 'asc' ? 'text-dark' : 'text-black-50'">&uarr;</span>
                    <span
                        :class="this.sort_field === 'created_at' && this.sort_direction === 'desc' ? 'text-dark' : 'text-black-50'">&darr;</span>
                </th>
                <th>Edit</th>
                <th>Delete</th>
            </tr>
            </thead>
            <tbody>
            <tr v-for="post in posts.data" :key="post.id">
                <td>{{ post.id }}</td>
                <td>{{ post.title }}</td>
                <td>{{ post.body.substring(0, 30) }}</td>
                <td>{{ post.created_at }}</td>
                <td>
                    <router-link :to="{ name:'posts.edit', params:{ id:post.id} }" class="btn btn-success">Edit
                    </router-link>
                </td>
                <td>
                    <button @click="delete_post(post.id)" class="btn btn-danger">Delete</button>
                </td>
            </tr>
            </tbody>
        </table>
        <pagination :data="posts" @pagination-change-page="getResults"></pagination>
    </div>
</template>


<script>
export default {
    data() {
        return {
            posts: {},
            categories: {},
            category_id: '',
            sort_field: 'created_at',
            sort_direction: 'desc',
        }
    },
    mounted() {
        axios.get('/api/category')
            .then(response => {
                this.categories = response.data.data;
            });
        this.getResults();
    },
    watch: {
        category_id(value) {
            this.getResults()
        }
    },
    methods: {
        change_sort(field) {
            if (this.sort_field === field) {
                this.sort_direction = this.sort_direction === 'asc' ? 'desc' : 'asc';
            } else {
                this.sort_field = field;
                this.sort_direction = 'asc';
            }
            this.getResults();
        },
        getResults(page = 1) {
            console.log(
                '/api/posts?page=' + page
                + '&category_id=' + this.category_id
                + '&sort_field=' + this.sort_field
                + '&sort_direction=' + this.sort_direction
            );
            axios.get('/api/posts?page=' + page
                + '&category_id=' + this.category_id
                + '&sort_field=' + this.sort_field
                + '&sort_direction=' + this.sort_direction)
                .then(response => {
                    this.posts = response.data;
                });
        },
        delete_post(id) {
            swal({
                title: "Are Your Shure You Want to Delete The Post ?",
                icon: "warning",
                buttons: ["No", "Yes"],
                dangerMode: true,
            })
                .then((willDelete) => {
                    if (willDelete) {
                        axios.delete('/api/posts/' + id).then(response => {
                            swal("Post Deleted Successfully");
                            this.getResults()
                        })
                    } else {
                        swal("Post Not Deleted");
                    }
                }).catch(error => {
                swal({
                    icon: 'error',
                    title: 'Error Happened'
                });
            });
        }
    }
}
</script>


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