ساخت add , edit , delete حرفه ای و به راحتی با vue.js

توی خیلی از پروژه ها مخصوصا فروشگاه های آنلاین ما همیشه باید یک سری چیزارو وارد کنیم ، ویرایش کنیم یا حذف کنیم

مثل محصول ، دسته بندی ها و یا هر مورد دیگه

خیلی وقتا بیشتر دولوپرا میان برای هر قسمت یک کامپوننت جدا تعریف میکنن و توی هر کامپوننت متد های post , patch , delete و ... با axios تعریف میکنن این روش کاملا درسته و مشکلی نداره

اما برای سریع تر شدن کار و کاهش خطا ما یه پکیج درست کردیم که این متد هارو توش داره و با همون axios هم کار میکنه و روش کارش هم خیلی سادست و مقادیرو توی لیست یا هرجا باشن براتون add , edit , delete میکنه

نمونه زنده این آموزش توی استک‌بلیتز ببینید :

https://stackblitz.com/edit/vue-kngugp

آموزش این پست توی آپارات :

https://www.aparat.com/v/V9cPN

آموزش این پست توی یوتوب :

https://www.youtube.com/watch?v=O8IABngqnNY

مزیت

مزیتی که این روش داره اینه که دیتا میتونه به صورت لیست یا تکی اضافه حذف و ویرایش بشه و خیلی کاربر پسند تره

شروع

از طریق npm نصبش کنید :

npm i @shopid/vue-editobj

کار کردن با این پکیچ هم خیلی سادست و تنها کاری که باید بکنید اینه که کامپوننتون رو از این کامپوننت extend کنید

مثلا میخوایم کامپوننت Product.vue یا همون محصول بسازیم :

نکته : سایت ویرگول (همین سایت) روی تگ script حساسه و حذفش میکنه هرجا دیدین نوشتم تگ‌اسکریپت خودتون بکنیدش script 😆

<template>
<input v-model="item.title" placeholder="title.." />
<input v-model="item.caption" placeholder="caption.." />
</template>

<تگ‌اسکریپت>
import editobj from '@shopid/vue-editobj';
export default {
extends: editobj,
name: 'product',
apiHost: 'http://127.0.0.1:8000/api',
apiPath:"product",
 apiConfig: {
  headers: {
   Authorization: 'Bearer ' + 'mytoken',
  },
  },
};
</تگ‌اسکریپت>

تنها کاری که باید بکنیم اینه که اول پکیج @shopid/vue-editobj ایمپورت کنیم و کامپوننتمون رو از اون extend کنیم (extends: editobj)

مقدار apiPath هم product میذاریم (این مقدار میچسبه به apiHost و آدرس api تشکیل میشه)

مقدار apiHost هم آدرس api بک‌اندمونه

مقدار apiConfig هم کانفیگ کردن مقادیری مثل هدر هست

حالا مثلا اگه apiHost برابر با http://127.0.0.1:8000/api بذاریم

آدرس api که خود کامپوننت اتوماتیک میسازه میشه :

http://127.0.0.1:8000/api/product

دوتا input هم توی تمپلیتمون داریم که اینجا عنوان و کپشن هست

تموم شد ! کامپوننت محصول ساخته شد و الان میتونه مقدار جدید بگیره مقادیر قبلیو ویرایش کنه ذخیره کنه یا حذف کنه

خب حالا چجوری ازش استفاده کنیم ؟

مثال :

یک کامپوننت میسازیم به اسم ProductList.vue

اول از همه Product که ساختیم ایمپورت میکنیم که ازش استفاده کنیم

بعد باید لیستی که میخوایم از بک‌اند بگیریم و با اون لیست Product بسازیم

اینجا توی دیتا خودمون یک سری محصول به صورت آبجکت میسازیم

اینجوری مثلا

products: [
{ id: 1, title: 'prod1', caption: 'cap1' },
{ id: 2, title: 'prod2', caption: 'cap2' },
{ id: 3, title: 'prod3', caption: 'cap3' },
]

حالا باید توی تمپلیت لوپ کنیم و بسازیمش همین !

اون پکیجه خودش برای هرکدوم ازینا متدای ذخیره و حذف و اینارو میسازه

تازه اگه به این لیست آیتم بدون id اضافه کنیم خودش تشخیص میده که این یه آیتم جدیده و اگه متد save اجرا بشه post میکنه اگه ببینه id داره patch میکنه به همین سادگی

لوپ کردن توی ویو هم که خیلی سادست :

با v-for توی products لوپ میکنیم و :item رو مساوی هر آبجکت میذاریم

یعنی :

<div v-for="product in products"  class="prodItem" :key="product.id" >
<Product :item="product" />
</div>

بعد دوتا دکمه میذاریم یکیش save یکیشم delete که وقتی روشون کلیک شد متد های save و delete همون آبجکت صدا زده بشه

این متد ها ورودی هم میگیرن که وقتی ذخیره شد یا حذف شد چه کاری انجام بدن

product.save({ onSaved: onSaved });

که onSaved هم یه متد توی ProductList هست که باید توی methods تعریفش کنید برای onDeleted هم به همین صورت

کامل تر :

<div v-for="product in products"  class="prodItem"  :key="product.id" >
<Product :item="product" />
<br />
<button @click="'product.save({ onSaved: onSaved });">save</button>
<br />
<button v-if="product.id" @click="product.delete({ onDeleted: onDeleted })">
delete
</button>
</div>

و متد ها

methods: {
onDeleted: function (item, resp) {
this.products = this.products.filter((loopItem) => loopItem !== item);
console.log(item);
console.log(resp);
this.status = resp.data.message;
},
onSaved: function (item, resp) {
console.log(item);
console.log(resp);
this.status = resp.data.message;
},
}

برای اضافه کردن هم کافیه یه دکمه بسازید و به products یه آبجکت جدید و خالی پوش کنید !

<button @click="products.push({})">addnew</button>


نسخه کامل ProductList.vue :

<template>
<div>{{ status }}</div>
<div class="prodItem" v-for="product in products" :key="product.id">
<Product :item="product" />
<br />
<button @click="status = 'saving ...';product.save({ onSaved: onSaved });">
save
</button>
<br />
<button v-if="product.id" @click="status = 'deleting ...';product.delete({ onDeleted: onDeleted })">
delete</button>
</div>
<button @click="products.push({})">addnew</button>
</template>
<تگ‌اسکریپت>
import Product from './Product.vue';
export default {
name: 'ProductList',
components: {
Product,
},
data: () => {
return {
products: [
{ id: 1, title: 'prod1', caption: 'cap1' },
{ id: 2, title: 'prod2', caption: 'cap2' },
{ id: 3, title: 'prod3', caption: 'cap3' },
],
status: 'idle',
};
},
methods: {
onDeleted: function (item, resp) {
this.products = this.products.filter((loopItem) => loopItem !== item);
console.log(item);
console.log(resp);
this.status = resp.data.message;
},
onSaved: function (item, resp) {
console.log(item);
console.log(resp);
this.status = resp.data.message;
},
},
};

</تگ‌اسکریپت>
<style>
.prodItem {
border: 1px solid black;
margin: 0.5rem;
padding: 0.5rem;
}
</style>