BLOG ب LARAVEL & VUE JS الجزء العاشر

imadbelasri Vuejs
VS

فهاد الجزء العاشر من blog ب laravel & vuejs غادي نزيدو الكود لي غادي يمكنا من حذف post إختاريناه أيضا غادي نزيدو الإمكانية ديال تعديل post.


نظرة سريعة بالفيديو


1- حذف post

باش نمسح post من قاعدة البيانات كنمشي ل AdminPanel كنزيد رابط الحذف لي فاش كنضغط عليه كنفذ ل fonction deletePost لي كتاخذ slug ديال ل post من بعد كتعرض رسالة تأكيد يلا ضغطت على نعم كيتمسح ل post من قاعدة البيانات.

الكود ديال AdminPanel بعد التعديل هو :

                                                    
                                                        //
<template>
  <div class="container">
    <div class="row mt-5 mb-3">
      <div class="col-md-12">
        <a
          data-target="#addPost"
          data-toggle="modal"
          class="btn mt-5 btn-sm btn-success text-white mb-2"
        >
          <i class="fa fa-plus"></i>
        </a>
        <table class="table">
          <thead>
            <tr>
              <th>Id</th>
              <th>Catégorie</th>
              <th>Titre</th>
              <th>Description</th>
              <th>Image</th>
              <th>Ajouté par</th>
              <th>Le</th>
              <th>Action</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(post,index) in posts.data" :key="index">
              <td>{{post.id}}</td>
              <td>{{post.category.name}}</td>
              <td>{{post.title}}</td>
              <td>{{post.body.substr(0,100)}}...</td>
              <td>
                <img
                  :src="post.photo"
                  class="img-fluid mr-2 rounded shadow-sm"
                  alt
                  height="60"
                  width="60"
                  srcset
                />
              </td>
              <td>{{post.user.name}}</td>
              <td>{{post.added}}</td>
              <td class="d-flex flex-row justify-content-center align-items-center">
                <router-link :to="post.path" class="btn mr-1 btn-sm btn-primary text-white">
                  <div class="fa fa-eye"></div>
                </router-link>
                <a @click="deletePost(post.slug)" class="btn btn-sm btn-danger">
                  <i class="fa fa-trash"></i>
                </a>
              </td>
            </tr>
          </tbody>
        </table>
        <div class="card-footer d-flex justify-content-center">
          <pagination :data="posts" @pagination-change-page="getPosts"></pagination>
        </div>
      </div>
      <AddPost @added="postAdded" />
    </div>
  </div>
</template>

<script>
import AddPost from "./AddPost";

export default {
  data() {
    return {
      posts: {},
      loading: true
    };
  },
  components: { AddPost },
  created() {
    if (User.isLogged() && User.isAdmin()) {
      this.getPosts();
    } else {
      this.$router.push({ name: "home" });
    }
  },
  methods: {
    getPosts(page) {
      if (typeof page === "undefined") {
        page = 1;
      }
      axios
        .get("/api/posts?page=" + page)
        .then(response => {
          console.log(response.data);
          this.posts = response.data;
        })
        .catch(err => console.log(err));
    },
    postAdded() {
      this.getPosts();
    },
    deletePost(slug) {
      Swal.fire({
        title: "êtes vous sûr?",
        text: "Vous ne pouvez pas récupérer cet article",
        type: "warning",
        showCancelButton: true,
        confirmButtonColor: "#3085d6",
        cancelButtonColor: "#d33",
        cancelButtonText: "Annuler",
        confirmButtonText: "Oui supprimer!"
      }).then(result => {
        if (result.value) {
          axios
            .delete(`/api/posts/${slug}`)
            .then(response => {
              Swal.fire({
                position: "center",
                type: "success",
                title: response.data.message,
                showConfirmButton: false,
                timer: 1500
              });
              this.getPosts();
            })
            .catch(error => console.log(error));
        }
      });
    }
  }
};
</script>
                                                    
                                                

2- إضافة ل component الخاص بالتعديل

من بعد غادي نمشي ل dossier components فيه غادي تزيد fichier جديد سميه EditPost.vue لي فيه غادي يكون الكود ديال التعديل.

بالنسبة للكود ديال التعديل هو نفس الكود لي زدنا ف AddPost الفرق هو هنا فقط كنسترجعوا ال post لي غادي نعدلوا ونعرضوا المعلومات ديالو فالفورم.

الكود ديال الملف هو :

                                                        
                                                            //
<template>
  <div class="container">
    <div class="row my-4">
      <div class="col-md-8 mx-auto mt-5">
        <div class="card bg-light">
          <h3 class="card-header" id="exampleModalCenterTitle">Modifier un article</h3>
          <div class="card-body">
            <form @submit="updatePost" enctype="multipart/form-data">
              <div class="form-group">
                <label for>Catégorie</label>
                <option value disabled selected>Veuillez choisir une catégorie</option>
                <select v-model="post.category" class="form-control" name="category" required id>
                  <option
                    :value="category.id"
                    v-for="(category,index) in categories"
                    :key="index"
                  >{{category.name}}</option>
                </select>
              </div>
              <div class="form-group">
                <label for>Titre*</label>
                <input
                  type="text"
                  name="title"
                  id
                  v-model="post.title"
                  class="form-control"
                  placeholder="Titre"
                  required
                  aria-describedby="helpId"
                />
              </div>
              <div class="form-group">
                <label for></label>
                <textarea
                  v-model="post.body"
                  class="form-control"
                  name="body"
                  id
                  rows="5"
                  placeholder="Description"
                ></textarea>
              </div>
              <div class="form-group">
                <label for>Photo*</label>
                <input
                  type="file"
                  v-on:change="onImageChange"
                  class="form-control-file"
                  name="image"
                  id="image"
                  placeholder
                  aria-describedby="fileHelpId"
                />
              </div>
              <button type="submit" class="btn btn-primary">Valider</button>
            </form>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      post: { title: "", body: "", category: "" },
      categories: [],
      image: null
    };
  },
  created() {
    this.getPost();
    this.getCategories();
  },
  methods: {
    onImageChange(e) {
      console.log(e.target.files[0]);
      this.image = e.target.files[0];
    },
    getCategories() {
      axios
        .get("/api/categories")
        .then(response => (this.categories = response.data.categories))
        .catch(err => console.log(err));
    },
    getPost() {
      axios
        .get(`/api/posts/${this.$route.params.slug}`)
        .then(res => {
          this.post = res.data.post;
          this.image = res.data.post.photo;
        })
        .catch(err => console.log(err));
    },
    updatePost(e) {
      e.preventDefault();
      const config = {
        headers: { "content-type": "multipart/form-data" }
      };
      let formData = new FormData();
      formData.append("image", this.image);
      formData.append("title", this.post.title);
      formData.append("body", this.post.body);
      formData.append("category_id", this.post.category);
      formData.append("user_id", User.isLogged().id);
      formData.append("_method", "put");
      axios
        .post(`/api/posts/${this.post.slug}`, formData, config)
        .then(res => {
          this.post.title = "";
          this.post.body = "";
          this.post.category = "";
          this.image = null;
          Swal.fire({
            position: "center",
            icon: "success",
            title: "Article modifié",
            showConfirmButton: false,
            timer: 1500
          });
          this.$router.push({ name: "admin" });
        })
        .catch(err => console.log(err));
    }
  }
};
</script>
                                                        
                                                    

3- إضافة route التعديل

باش يمكنا نديرو التعديل خاص نزيدو route الخاص بالتعديل غادي نمشي ل fichier routes.js فيه كنسترجع ل component EditPost ولي كنزيد route الخاص به ولي كياخذ slug ك paramétre.

الكود ديال الملف routes.js بعد التعديل هو :

                                                        
                                                            //
import Vue from 'vue'
import VueRouter from 'vue-router'


import Home from '../components/Home.vue';
import PostDetails from '../components/PostDetails.vue';
import PostCategory from '../components/PostCategory.vue';
import Login from '../components/Login.vue';
import Signup from '../components/Signup.vue';
import Logout from '../components/Logout.vue';
import AdminPanel from '../components/AdminPanel.vue';
import EditPost from '../components/EditPost.vue';


Vue.use(VueRouter)


const routes = [
    {
        path: '/', component: Home, name: 'home'
    },
    {
        path: '/login', component: Login, name: 'login'
    },
    {
        path: '/signup', component: Signup, name: 'signup'
    },
    {
        path: '/logout', component: Logout, name: 'logout'
    },
    {
        path: '/post/:slug',
        component: PostDetails,
        name: 'postDetails'
    },
    {
        path: '/post/edit/:slug',
        component: EditPost,
        name: 'editPost'
    },
    {
        path: '/posts/category/:slug',
        component: PostCategory,
        name: 'postCategory'
    },
    {
        path: '/admin',
        component: AdminPanel,
        name: 'admin'
    }
];

const router = new VueRouter({
    routes,
    hashbang: false,
    mode: 'history'
})

export default router;
                                                        
                                                    

4- إضافة رابط التعديل

غادي نرجع ل AdminPanel ونزيد رابط التعديل لي كيدي ل route لي زدنا مع slug ديال ل post لي بغينا نعدلوا.

دبا ل admin ديالنا غادي يخدم كما بغينا بقاو ل users ول catégories ممكن تزيدهم وهذا تمرين ليلك باش تعرف واش قادر تخدم بوحدك.

الكود ديال الملف AdminPanel بعد التعديل هو :

                                                        
                                                            //
<template>
  <div class="container">
    <div class="row mt-5 mb-3">
      <div class="col-md-12">
        <a
          data-target="#addPost"
          data-toggle="modal"
          class="btn mt-5 btn-sm btn-success text-white mb-2"
        >
          <i class="fa fa-plus"></i>
        </a>
        <table class="table">
          <thead>
            <tr>
              <th>Id</th>
              <th>Catégorie</th>
              <th>Titre</th>
              <th>Description</th>
              <th>Image</th>
              <th>Ajouté par</th>
              <th>Le</th>
              <th>Action</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(post,index) in posts.data" :key="index">
              <td>{{post.id}}</td>
              <td>{{post.category.name}}</td>
              <td>{{post.title}}</td>
              <td>{{post.body.substr(0,100)}}...</td>
              <td>
                <img
                  :src="post.photo"
                  class="img-fluid mr-2 rounded shadow-sm"
                  alt
                  height="60"
                  width="60"
                  srcset
                />
              </td>
              <td>{{post.user.name}}</td>
              <td>{{post.added}}</td>
              <td class="d-flex flex-row justify-content-center align-items-center">
                <router-link :to="post.path" class="btn mr-1 btn-sm btn-primary text-white">
                  <div class="fa fa-eye"></div>
                </router-link>
                <router-link
                  :to="{path: '/post/edit/' + post.slug}"
                  class="mr-1 btn btn-sm btn-warning"
                >
                  <i class="fa fa-edit"></i>
                </router-link>
                <a @click="deletePost(post.slug)" class="btn btn-sm btn-danger">
                  <i class="fa fa-trash"></i>
                </a>
              </td>
            </tr>
          </tbody>
        </table>
        <div class="card-footer d-flex justify-content-center">
          <pagination :data="posts" @pagination-change-page="getPosts"></pagination>
        </div>
      </div>
      <AddPost @added="postAdded" />
    </div>
  </div>
</template>

<script>
import AddPost from "./AddPost";

export default {
  data() {
    return {
      posts: {},
      loading: true
    };
  },
  components: { AddPost },
  created() {
    if (User.isLogged() && User.isAdmin()) {
      this.getPosts();
    } else {
      this.$router.push({ name: "home" });
    }
  },
  methods: {
    getPosts(page) {
      if (typeof page === "undefined") {
        page = 1;
      }
      axios
        .get("/api/posts?page=" + page)
        .then(response => {
          console.log(response.data);
          this.posts = response.data;
        })
        .catch(err => console.log(err));
    },
    postAdded() {
      this.getPosts();
    },
    deletePost(slug) {
      Swal.fire({
        title: "êtes vous sûr?",
        text: "Vous ne pouvez pas récupérer cet article",
        type: "warning",
        showCancelButton: true,
        confirmButtonColor: "#3085d6",
        cancelButtonColor: "#d33",
        cancelButtonText: "Annuler",
        confirmButtonText: "Oui supprimer!"
      }).then(result => {
        if (result.value) {
          axios
            .delete(`/api/posts/${slug}`)
            .then(response => {
              Swal.fire({
                position: "center",
                type: "success",
                title: response.data.message,
                showConfirmButton: false,
                timer: 1500
              });
              this.getPosts();
            })
            .catch(error => console.log(error));
        }
      });
    }
  }
};
</script>
                                                        
                                                    

دروس ذات صلة

VS

آلة حاسبة بإ ستعمال Vuejs

فهاد الدرس الأول من سلسلة vuejs غادي نشوفو كيفاش نقادو آلة حاسبة بإستعمال vuejs فالناس لي مكتعرفش شن...


VS

كيفاش نصاوب Note App ب Vuejs

فهاد الدرس الثاني من سلسلة vuejs غادي نشوفو كيفاش نقادو Note App بإستعمال vuejs فحنا فهاد الدرس ال...


VS

Application de gestion de dépenses باستعمال Vuejs

فهاد الدرس الجديد من سلسلة vuejs غادي نشوفو كيفاش نقادو une simple application كتدير la gestion de d...


VS

Ecommerce App باستعمال Vuejs

فهاد الدرس الجديد من سلسلة vuejs غادي نشوفو كيفاش نقادو Ecommerce App المستخدم كيزيد des produits فل...


VS

login système ب laravel & vue js الجزء الأول

فهاد الدرس الجديد غادي نشوفوا كيفاش نقادو login système ب laravel & vue js فل projet بسيط غادي يكون...


VS

LOGIN SYSTÈME ب LARAVEL & VUE JS الجزء الثاني

فهاد الجزء الثاني من LOGIN SYSTÈME ب LARAVEL & VUE JS غادي نشوفوا كيفاش نزيدو les components vue js...


VS

login système + Vote systéme ب laravel & vue js الجزء الثالت

فهاد الجزء الثالت من login système + vote systéme ب laravel & vue js كيف قلنا فل ل video...


VS

LOGIN SYSTÈME + VOTE SYSTÉME ب LARAVEL & VUE JS الجزء الرابع

فهاد الجزء الرابع من LOGIN SYSTÈME + VOTE SYSTÉME ب LARAVEL & VUE JS غادي نعرضوا les posts ديال...


VS

CRUD application ب php & vuejs الجزء الأول

فهاد ل projet الجديد غادي نشوفوا كيفاش نقادوا CRUD application ب php و vue js ولي سبق ودرناها...


VS

CRUD application ب php & vuejs الجزء الثاني

فهاد الجزء الثاني من CRUD application ب php و vue js غادي نكملوا ل projet ديالنا وندوزو للجزء الخاص...