Sinau Coding
Berbincang santai perihal pemrograman
Tukang ketik yang sedang belajar pemrograman
7/19/2019 12:00:00 AM

Vue+Vuetify : Menggunakan VDialog/v-dialog agar menjadi Promise based komponen


Vuetify 2

Jika anda menggunakan Vue dan Vuetify, maka VDialog/v-dialog mungkin adalah komponen yang selalu atau sering anda gunakan. Cara standar untuk menggunakan v-dialog adalah dengan menempatkannya menjadi satu pada halaman yang membutuhkan, lalu men-show-hide dialog dengan menggunakan v-model.

Cara seperti ini sebenarnya dapat lebih disederhanakan lagi, yaitu dengan memisahkan dialog tersebut menjadi komponen terpisah dan memanggilnya hanya dengan fungsi tertentu, misalkan open() yang mengembalikan Promise.

Dengan cara di atas, maka Dialog anda akan menjadi lebih terstruktur, modular dan lebih sederhana dikarenakan Dialog tersebut dapat di-import di semua tempat dan lebih mudah karena hanya perlu menunggu respon dari Promise, apakah resolve atau reject.  Tidak perlu bingung lagi tombol apakah yang ditekan user, apakah OK atau SAVE atau CANCEL atau yang lain, melainkan cukup hanya melihat data yang dikembalikan jika resolve atau reject.

Berikut ini adalah contoh bagaimana cara untuk menggunakan dan menyederhanakan dialog agar menjadi promise-based komponen.

1. Memisahkan Dialog

Langkah pertama adalah memisahkan komponen Dialog yang anda buat. Kebiasaan saya pribadi adalah membuat folder bernama components di root folder yang berisi semua komponen global. Silahkan buat komponen Dialog anda (misalkan diberi nama MDialog) pada folder components tersebut atau pada folder lain yang anda inginkan. Kira-kira bentuk dari komponen MDialog tersebut adalah sebagai berikut.

Kode:


<template>
  <v-dialog v-model="dialog" width="600">
    <v-card>
      <v-card-title class="headline grey lighten-2" primary-title>
This is My Dialog
      </v-card-title> 
      <v-card-text>
Lorem ipsum dolor sit amet, consectetur 
adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip 
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit 
esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat 
non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </v-card-text>
      <v-divider></v-divider>
      <v-card-actions>
        <v-btn color="default">Batal</v-btn>
        <v-spacer></v-spacer>
        <v-btn dark color="green">Ok</v-btn>
        <v-btn dark color="blue">No</v-btn>
        <v-btn dark color="purple">Ya</v-btn>
        <v-btn dark color="red">Tidak</v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>
 
<script>
export default {
  data: () => ({
    dialog: false,
  }),
  methods: {
  }
};
</script>

Komponen MDialog di atas akan kita buat agar dapat dipanggil hanya dengan 1 method/function saja. Misalkan method/function tersebut bernama open. Method open ini akan mengembalikan Promise dimana promise tersebut akan di-resolve jika user menekan tombol Ok, No, Ya dan Tidak dengan return berupa String yang sesuai dengan nama tombol, dan akan di-reject jika user menekan tombol Batal.

2. Menambahkan methods Open yang mengembalikan Promise
Tambahkan pada data, dua buah variable yaitu resolve dan reject. Dimana resolve akan digunakan untuk menyimpan function resolve dan reject untuk function reject dari object Promise.


<script>
export default {
  data: () => ({
    dialog: false,
    resolve : null,
    reject : null,
  })
};
</script>

Setelah itu tambahkan juga 1 buah method bernama open. Dimana pada method open tersebut akan secara otomatis membuat object Promise dan men-show dialog dengan cara men-set nilai data dialog dari false menjadi true.


<script>
export default {
  data: () => ({
    dialog: false,
    resolve : null,
    reject : null,
  }),
 
  methods:{
    open(){
      return new Promise((resolve, reject)=>{
        this.resolve = resolve
        this.reject = reject
 
        this.dialog = true
      })
    }
  }
};
</script>

Yang perlu kita perhatikan dari methods open ini adalah, konstruktor kelas Promise yang memiliki 1 argumen yaitu sebuah function dengan 2 buah argumen berupa function, yaitu resolve dan reject.

new Promise(executor);
Pada kode di atas, pada saat meng-inisialisasi object Promise, function resolve kita simpan ke dalam variable/data resolve dan function reject juga kita simpan ke dalam variable/data reject. Perhatikan juga bahwa methods open akan langsung mengembalikan (return) Promise tersebut.

Jika anda masih bingung dengan Promise, maka sebaiknya anda pelajari lebih lanjut tentang Promise, salah satunya dari link ini : developer.mozilla.org Promise.


Baca juga :
Cara install dan integrasi GrapesJS dengan Vue 2

Selanjutnya kita buat 2 buah method untuk menutup dialog sebagai resolve dan sebagai reject, misalkan kita beri nama accept dan cancel. Masing-masing methods tersebut menerima 1 argumen yang akan dikembalikan dalam Promise. Tujuan dari methods accept ini adalah menutup dialog dan memanggil function resolve sehingga Promise akan masuk ke then. Dan tujuan dari cancel adalah untuk menutup dialog dan memanggil function reject sehingga Promise akan masuk ke catch.


methods: {
    open() {
      return new Promise((resolve, reject) => {
        this.resolve = resolve;
        this.reject = reject;
 
        this.dialog = true;
      });
    },
    accept(str) {
      this.dialog = false;
      this.resolve(str);
    },
    cancel(str) {
      this.dialog = false;
      this.reject(str);
    }
}

Selanjutnya kita pasang methods tersebut ke tombol-tombol yang sesuai.


<v-card-actions>
   <v-btn @click="cancel('batal')" color="default">Batal</v-btn>
   <v-spacer></v-spacer>
   <v-btn @click="accept('Ok')" dark color="green">Ok</v-btn>
   <v-btn @click="accept('No')" dark color="blue">No</v-btn>
   <v-btn @click="accept('Ya')" dark color="purple">Ya</v-btn>
   <v-btn @click="accept('Tidak')" dark color="red">Tidak</v-btn>
</v-card-actions>

Sampai di sini maka MDialog kita sudah selesai dan siap untuk digunakan.

3. Menggunakan komponen MDialog

Setelah komponen MDialog selesai, maka kini saatnya untuk menggunakan komponen tersebut. Pada contoh kali ini, komponen MDialog tersebut akan saya gunakan pada halaman utama dari aplikasi saya, yaitu pada App.vue (Ini hanya contoh dan tentu saja anda dapat menggunakan komponen MDialog anda di sembarang halaman).

Kira-kira seperti ini lah bentuk halaman utama aplikasi ini. Sangat sederhana, hanya ada 1 tombol untuk membuka Dialog dan 1 div untuk menampilkan hasil dari tombol yang ditekan user.

Kode :


<template>
  <v-app>
    <v-content>
      <v-container fill-height>
        <v-layout column fill-height align-center justify-center>
          <div class="body-2">Hasil dialog : {{hasil || '-'}}</div>
          <div>
            <v-btn color="primary">Open Dialog</v-btn>
          </div>
        </v-layout>
      </v-container>
    </v-content>
  </v-app>
</template>
 
<script>
export default {
  name: "App",
  components: {},
  data: () => ({
    hasil: ""
  }),
  methods: {}
};
</script>

Yang akan kita lakukan adalah, jika user menekan tombol Open Dialog, maka dialog MDialog kita akan muncul. Kemudian apapun tombol yang ditekan user maka hasilnya akan ditampilkan di dalam div hasil tersebut di atas.

Langkah pertama adalah mendaftarkan komponen MDialog dengan terlebih dahulu meng-import file MDialog.


<script>
import MDialog from "./components/MDialog.vue";
export default {
  name: "App",
  components: {
    MDialog
  },
  data: () => ({
    hasil: ""
  }),
  methods: {}
};
</script>

Pastikan anda tidak lupa untuk menambahkan MDialog ke dalam components.

Selanjutnya tambahkan komponen MDialog ke dalam halaman/template. Silahkan tempatkan disembarang tempat, tetapi saya sarankan berada di paling bawah tetapi tetap harus ada di dalam 1 root komponen. Setelah itu tambahkan ref kepada MDialog tersebut, misalkan kita beri referensi bernama dlg.


<template>
  <v-app>
    <v-content>
    . . .
    </v-content>
 
    <MDialog ref="dlg"/>
 
  </v-app>
</template>

Dengan menambahkan referensi (ref) ini, maka komponen MDialog tersebut di atas dapat di panggil via script dengan nama referensinya. Jika anda lupa atau kurang paham tentang apa itu ref dan $refs, silahkan cek penjelasannya di link berikut ini : https://vuejs.org/v2/api/#ref.

Selanjutnya, kita buat 1 buah methods untuk memanggil dan menampilkan MDialog beserta hasilnya. Dan tempatkan methods tersebut pada tombol Open Dialog.


<template>
  . . .
  <v-btn @click="openDialog" color="primary">Open Dialog</v-btn>
  . . .
</template>
  . . .
  methods: {
    openDialog() {
      this.$refs.dlg
        .open()
        .then(res => {
          this.hasil = res;
        })
        .catch(res => {
          this.hasil = res;
        });
   }
}

Penjelasan:

this.$refs.open();

Statement di atas artinya kita memanggil komponen MDialog yang dalam hal ini dipanggil via $refs. Kemudian kita panggil methods open dari MDialog dimana methods open ini mengembalikan Promise.

 .then(res => {
     this.hasil = res;
 })
 .catch(res => {
     this.hasil = res;
});

then adalah rantai yang akan dipanggil oleh Promise jika Promise tersebut resolve (User menekan tombol Ok, No, Ya, Tidak. Dan catch adalah rantai yang akan dipanggil oleh Promise jika Promise tersebut di reject (User menekan tombol Batal). Hasil dari Promise tersebut kemudian ditampilkan ke dalam div.

Selesai.

Mudah-mudahan penjelasan ini tidak membingungkan dan anda dapat mengikuti setiap langkahnya serta dapat memahami dan menggunakan cara ini untuk keperluan anda. Jika ada yang kurang jelas atau ada informasi yang salah, jangan ragu-ragu untuk menuliskannya di dalam komentar.

Sekian, selamat mencoba dan semoga yang sedikit ini bermanfaat.

Catatan :
Penggunaan ref menjadi suatu keharusan jika anda menggunakan cara ini. Oleh karena itu anda harus mengetahui batasan dari penggunaan ref ini. Salah satunya adalah, ref menjadi tidak berfungsi jika ref berada di dalam kalang v-if. Setidaknya sampai dengan tulisan ini ditulis.

Hasil akhir dan kode lengkap.


Komentar

Load more