Upload gambar adalah salah satu fitur paling populer di web modern. Tetapi dari semua komponen yang dapat membentuk sebuah formulir, komponen pengunggahan gambar bisa menjadi salah satu yang paling membuat frustasi bagi banyak pengembang karena menuntut banyak usaha dan gaya. Dan itulah mengapa saya membuat paket vue-media-upload.
Vue-Media-Upload adalah paket Vue yang mudah diatur untuk mengupload banyak gambar dengan preview yang mendukung form create dan update , dan itu akan menangani upload untuk Anda melalui request ajax.
Untuk tutorial ini, kami akan membuat formulir sederhana di mana Anda juga dapat mengunggah gambar menggunakan Laravel 9, Vue 3 dan Bootstrap 5 . Seperti yang Anda lihat, upload media melihat preview image, bukan hanya bidang file input.
Langkah 1: Pengaturan Backend
Pertama-tama, mari kita stat dengan backend dengan menyiapkan database.
kita akan membutuhkan dua tabel, tabel posts
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('description');
$table->timestamps();
});
dan tabel images
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->foreignId('post_id')->constrained();
$table->string('name');
$table->timestamps();
});
dan jangan lupa untuk mengatur Model Anda juga.
Langkah 2: Instalasi Media-Upload
Anda dapat menginstal media-upload melalui npm:
$ npm install vue-media-upload
atau melalui yarn
$ yarn add vue-media-upload
setelah instalasi Anda dapat mengimpornya ke app.js file Anda
require('./bootstrap');
import { createApp } from 'vue';
import { UploadMedia, UpdateMedia } from 'vue-media-upload';
let app=createApp({})
app.component('upload-media' , UploadMedia);
app.component('update-media' , UpdateMedia);
app.mount("#app")
Langkah 3: Buat/Tambahkan Form
Di kami, create.blade.php kami akan membuat dua input dan menggunakan <upload-media/>komponen
<form action="{{route('post.create')}}" method="post">
@csrf
<div class="form-group">
<label for="">Title</label>
<input type="text" name="title" class="form-control @error('title') is-invalid @enderror" value="{{old('title')}}
</div>
<div class="form-group mt-3">
<label for="">Description</label>
<textarea name="description" rows="4" class="form-control @error('title') is-invalid @enderror">{{old('description')}}</textarea>
</div>
<div class="mt-3">
<label for="" class="m-0">Media</label>
<div id="app">
<upload-media
server='/api/upload'
error="@error('media'){{$message}}@enderror">
</upload-media>
</div>
</div>
<button class="btn btn-primary text-white mt-4">Submit</button>
</form>
Penggunaan
Sekarang kita perlu menambahkan baris ini di api.php
//upload image
Route::post('/upload', [ImageController::class, 'store'])->name('upload');
Di ImageController kami akan membuat fungsi store( )
yang menyimpan sementara gambar yang diunggah di tmp\uploads.
public function store(Request $request){
$path = public_path('tmp/uploads');
if (!file_exists($path)) {
mkdir($path, 0777, true);
}
$file = $request->file('image');
$name = uniqid() . '_' . trim($file->getClientOriginalName());
$file->move($path, $name);
return ['name'=>$name];
}
store()
function akan memberikan nama unik pada gambar yang diunggah dan menyimpannya di tmp/upload, dan akan mengembalikan nama unik ke <upload-media />
komponen sehingga dapat melanjutkan pekerjaannya.
Buat Controller Post
Setting web.php
Route::get('/post/create', [PostController\Create::class, 'index']);
Route::post('/post/create', [PostController\Create::class, 'store'])->name('post.create');
Dan di controller buat kami , seperti PostController/Create.php inilah store()
fungsinya
public function store(Request $request){
$this->validate($request,[
'title'=>'required',
'description'=>'required',
'media'=>'required',
]);
$post = Post::create([
'title'=>$request->title,
'description'=>$request->description,
]);
foreach($request->media as $image){
$from = public_path('tmp/uploads/'.$image);
$to = public_path('post_images/'.$image);
File::move($from, $to);
$post->images()->create([
'name' => $image,
]);
}
$posts = Post::get();
return redirect()->route('post.dashboard', ['posts'=>$posts]);
}
Kode ini hanya menyimpan kiriman dan menggunakan nama image unik untuk memindahkan gambar yang ditambahkan dari /tmp/uploads file lokasi sementara ke lokasi akhirnya /post_images.
Perhatikan bahwa tmp/uploads dan /post_images direktori perlu dibuat!
Langkah 4: Update/Edit Form
Dalam form update, update.blade.php kita perlu menggunakan komponen kedua <update-media/>
<form action="{{route('post.update', $post->id)}}" method="post">
@csrf
<div class="form-group">
<label for="">Title</label>
<input type="text" name="title" class="form-control" value="{{$post->title}}" required>
</div>
<div class="form-group mt-3">
<label for="">Description</label>
<textarea name="description" rows="4" class="form-control" required>{{$post->description}}</textarea>
</div>
<div class="mt-3" id="app">
<update-media
server='/api/upload'
media_file_path='/post_images'
media_server="/api/media/{{$post->id}}"
error="@error('media'){{$message}}@enderror">
</update-media>
</div>
<button class="btn btn-primary text-white mt-4">Save</button>
</form>
akan membutuhkan nama image yang disimpan untuk mempratinjaunya, jadi jangan lupa untuk menambahkan baris ini di api.php.
//return post images
Route::get('/media/{post}', [ImageController::class, 'getImages'])->name('post.images');
dan juga kita harus menambahkan fungsi getImages
di ImageController
public function getImages(Post $post){
$images = $post->images;
return ['media'=>$images];
}
Update Controller Post
kita perlu menambahkan dua baris ini di web.php.
Route::get('/post/update/{post}',[PostController\Update::class, 'index']);
Route::post('/post/update/{post}',[PostController\Update::class, 'update'])->name('post.update');
Dan akhirnya kita akan membutuhkan sebuah fungsi update()
di PostController/Update.php.
public function update(Post $post, Request $request){
$this->validate($request,[
'title'=>'required',
'description'=>'required',
'media'=>'required',
]);
$post->update($request->all());
if(isset($request->added_media)){
foreach($request->added_media as $image){
$from = public_path('tmp/uploads/'.$image);
$to = public_path('post_images/'.$image);
File::move($from, $to);
$post->images()->create([
'name' => $image,
]);
}
}
if(isset($request->deleted_media)){
foreach($request->deleted_media as $deleted_media){
File::delete(public_path('post_images/'.$deleted_media));
Image::where('name', $deleted_media)->delete();
}
}
$posts = Post::get();
return redirect()->route('post.dashboard', ['posts'=>$posts]);
}
fungsi ini pada dasarnya menambahkan gambar yang ditambahkan dan menghapus gambar yang dihapus.
upload multiple image laravel vue vue js laravel