andriajah Fri Aug 2022 1 year ago

Cara Upload Multiple Image dengan Preview di Laravel dan Vue

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