توی خیلی از پروژه ها مخصوصا فروشگاه های آنلاین ما همیشه باید یک سری چیزارو وارد کنیم ، ویرایش کنیم یا حذف کنیم
مثل محصول ، دسته بندی ها و یا هر مورد دیگه
خیلی وقتا بیشتر دولوپرا میان برای هر قسمت یک کامپوننت جدا تعریف میکنن و توی هر کامپوننت متد های post , patch , delete و ... با axios تعریف میکنن این روش کاملا درسته و مشکلی نداره
اما برای سریع تر شدن کار و کاهش خطا ما یه پکیج درست کردیم که این متد هارو توش داره و با همون axios هم کار میکنه و روش کارش هم خیلی سادست و مقادیرو توی لیست یا هرجا باشن براتون add , edit , delete میکنه
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>