Menggunakan Component di Vuejs

Menggunakan Component di Vuejs

Dalam beberapa artikel sebelumnya, seperti Membuat Component yang kemudian dilanjutkan dengan materi lanjutan dalam mengenali component dari Vue.js, hingga kita telah mencoba bagaimana membuat dynamic component. Maka pada kesempatan kali ini, akan dirangkai secara keseluruhan dengan case yang sedikit lebih kompleks.

Adapun point of content yang akan dibahas diantaranya:

  1. Creating & Registering Component

  2. Make form validation

  3. Berkomunikasi dengan Component

Baca Juga: Simple Validation With Vuejs

Creating & Registering Component

Case yang akan diangkat adalah dengan membuat sebuah form untuk mengisi biodata diantranya: nama lengkap dan email. Form ini dianggap sebagai satu component, kemudian component lainnya adalah untuk menampilkan data yang telah di isi pada component sebelumnya.

Pertama, buat file index.html kemudian masukkan kerangka berikut:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Component Vuejs</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
</head>
<body>
    <div class="container" id="dw">
        <div class="row" style="padding-top: 20px">
            <div class="col-md-6">
                <div class="card">
                    <div class="card-header">
                        Biodata
                    </div>
                    <div class="card-body">
                        <!-- ISI -->
                    </div>
                    <div class="card-footer">
                        <button class="btn btn-primary btm-sm"
                        >
                            Save
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
​
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
        new Vue({
            el: '#dw'
        })
    </script>
</body>
</html>

Langkah selanjutnya adalah membuat component untuk form pengisian biodata:

<script type="text/x-template" id="biodataform">
   <div>
      <div class="form-group">
          <label for="">Nama Lengkap</label>
          <input type="text" 
              class="form-control" 
              v-model="data.nama"
              >
      </div>
      <div class="form-group">
          <label for="">Email</label>
          <input type="email" 
              class="form-control" 
              v-model="data.email"
              >
      </div>
   </div>
 </script>

Kemudian register component diatas:

Vue.component('biodata', {
    template: '#biodataform',
    data() {
      return {
         data: {
             nama: '',
             email: ''
         }
      }
    },
    mounted() {
        this.data = {
            nama: '',
            email: ''
        }
    }
})

Penjelasan: Component ini diberi nama biodata yang memiliki dua buah form yakni nama dan email. Adapun mounted() berisi code untuk mengosongkan form ketika component di-load.

Tahap kedua, buat component lainnya untuk menampilkan biodata yang telah di-input:

<script type="text/x-template" id="showform">
    <div>
        <table class="table table-hover">
            <tr>
                <th>Nama Lengkap</th>
                <td>:</td>
                <td></td>
            </tr>
            <tr>
                <th>Email</th>
                <td>:</td>
                <td></td>
            </tr>
        </table>
    </div>
</script>

Jangan lupa untuk me-register component ini:

Vue.component('showprofile', {
    template: '#showform'
})

Penjelasan: Component ini diberi nama showprofile yang akan me-load template dengan id #showform.

Sekarang, kedua component yang dibutuhkan sudah bisa digunakan, maka mari kita lengkapi root instance terlebih dahulu dengan melakukan modifkasi seperti berikut:

new Vue({
  el: '#dw',
  data: {
      show: 'biodata',
      button: false,
      buttonTitle: 'Save',
      data: {}
  },
})

Penjelasan: show akan berisi nama dari component yang secara otomatis akan menampilkan component sesuai dengan value-nya. button nilainya false yang nantinya akan digunakan untuk memberikan efek loading apabila tombol ditekan. buttonTitle value-nya Save yang nantinya akan berganti sesuai dengan component yang di-load. data: {} nantinya akan menampung value yang dikirim dari component.

Kemudian modifikasi kerangka htmlnya, pada bagian card-body tambahkan code berikut:

<div v-if="show == 'biodata'">
    <biodata />
</div>
<div v-else>
    <showprofile />
</div>

Penjelasan: Apabila show memiliki value biodata maka yang akan di-load adalah component biodata. Selain itu maka akan me-load component showprofile.

Lalu pada bagian button modifikasi menjadi:

<button class="btn btn-primary btm-sm"
    :disabled="button"
>
    {{ button ? 'Loading...':buttonTitle }}
</button>

Penjelasan: Apabila button bernilai true maka akan di-binding disabled property sehingga tombol tidak bisa diklik. {{ button ? 'Loading...':buttonTitle }}, apabila button bernilai true, maka teks pada tombol menjadi Loading..., selain itu akan menampilkan teks sesuai dari value buttonTitle.

Component di Vuejs

Sebelum melanjutkan ke bagian selanjutnya, saya ingin menyatukan persepsi bahwa component pertama kita akan menyebutnya sebagai biodata dan component kedua kita akan menyebuatkan sebagai showprofile sesuai dengan nama component masing-masing. So, sepanjang pembahasan ini hanya akan disebutkan nama dari masing-masing component.

Make form validation

Sub bab ini telah dibahas pada materi Simple Validation with Vue.js. Kamu bisa membacanya terlebih dahulu sebelum melanjutkan agar tidak bingung kedepannya. Buat computed property di dalam biodata:

computed: {
    valName() {
        if (this.data.nama.length === 0 || this.data.nama.length > 50) {
            return true;
        } 
        return false;
    },
    valEmail() {
        var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        if (re.test(this.data.email)) {
            return false;
        }
        return true;
    }
}

Kemudian lakukan modifikasi pada template component ini dengan menambahkan class binding berikut pada masing-masing form:

//form nama lengkap
:class="{ 'is-invalid': valName }"
​
//form email
:class="{ 'is-invalid': valEmail }"

Berkomunikasi dengan Component

Pada tahap ini, yang akan dilakukan adalah berinteraksi dengan component. Adapun flow yang diinginkan adalah ketika tombol Save ditekan, dan validasinya tidak memberikan error maka akan mengambil data dari biodata yang kemudian dikirimkan ke showprofile.

Tahap pertama, modifikasi button terlebih dahulu dengan menambahkan event click, sehingga menjadi:

<button class="btn btn-primary btm-sm"
    @click="saveData"
    :disabled="button"
>
    {{ button ? 'Loading...':buttonTitle }}
</button>

Penjelasan: Ketika tombol di klik maka akan memanggil method saveData.

Kemudian buat method berikut pada root instance:

methods: {
   saveData() {
       this.button = true
       if (this.show == 'biodata' && !this.$refs.form.valName && !this.$refs.form.valEmail) {
           setTimeout(() => {
               this.$refs.form.submitForm()
               this.show = 'showprofile'
               this.buttonTitle = 'Back'
               this.button = false
           }, 1000)
       } else {
           setTimeout(() => {
               this.data = {}
               this.show = 'biodata'
               this.button = false
               this.buttonTitle = 'Save'
            }, 500)
        }
    }
}

Penjelasan:

  1. Mengubah value dari button menjadi true.

  2. Mengecek, jika value dari show adalah biodata dan value dari valName dan valEmail tidak bernilai true maka akan menjalan perintah yang ada didalam block if.

  3. Dimana, kita mengatur timeout selama 1 detik kemudian mengakses method submitForm yang terdapat didalam component biodata. Lalu mengubah value dari show, buttonTitle dan mengembalikan value dari button menjadi false. Adapun penjelasan mengenai this.$refs.form akan dibahas setelah ini.

  4. Selain itu, kita mengatur timeout menjadi 0,5 detik dengan mengembalikan value menjadi seperti sebelumnya.

Mungkin diantara teman-teman bertanya, apa sih kegunaan dari this.$refs.form? Fungsi dari $refs adalah untuk mengakses method dari component lain. Sedangkan form dari mana? form merupakan value dari ref yang didefinisikan ketika memanggil component.

Lakukan modifikasi pada penggunaan component biodata menjadi:

<biodata ref="form" />

Karena kita akan mengakses method submitForm, maka buat method tersebut di dalam component biodata:

methods: {
    submitForm() {
        this.$emit('send-data', this.data)
    }
},

Penjelasan: this.$emit digunakan untuk mengirimkan nilai ke parent. Adapun parameter pertama adalah custom name dan parameter selanjutnya adalah value yang akan dikirimkan.

Untuk menangkap value yang dikirim dari child component, maka lakukan modifikasi kembali pada penggunakan component biodata, menjadi:

<biodata ref="form"
    @send-data="getData"
/>

Penjelasan: send-data merupakan custom name yang berisi value yang dikirimkan dari child component. Sedangkan getData adalah methods yang akan menerima value yang dikirimkan.

Maka buat method getData pada root instance:

getData(value) {
    this.data = {
        nama: value.nama,
        email: value.email
    }
}

Nah! Sekarang data: {} telah berisi data yang diterima dari child component. Karena data yang diterima akan ditampilkan pada component showprofile, maka data ini akan dikirimkan kembali ke component tersebut.

Untuk mengirimkan data dari parent ke child bisa menggunakan props, sedangkan untuk mengirim data dari child ke parent bisa menggunakan $emit. Karena kondisinya kita akan mengirimkan data dari parent ke child, maka tambahkan props pada child component showprofile:

Vue.component('showprofile', {
    template: '#showform',
    props: ['data']
})

Kemudian modifikasi pada penggunakan component showprofile menjadi:

<showprofile :data="data" />

Penjelasan: Kita mengirimkan props dengan nama data yang valuenya diambil dari variable data (baca: data: {}) di dalam root instance vue.

Terakhir adalah menampilkan data yang diterima ke dalam component showprofile. Lakukan modifikasi menjadi:

<script type="text/x-template" id="showform">
    <div>
        <table class="table table-hover">
            <tr>
                <th>Nama Lengkap</th>
                <td>:</td>
                <td>{{ data.nama }}</td>
            </tr>
            <tr>
                <th>Email</th>
                <td>:</td>
                <td>{{ data.email }}</td>
            </tr>
        </table>
    </div>
</script>

Component di Vuejs

Component di Vuejs

Baca Juga: Filtering & Formatting Vuejs

Kesimpulan

Component didalam Vuejs sangat berguna dalam mengelola data maupun membuat code yang dibuat menjadi maintainable. Sehingga, apabila kita ingin melakukan perubahan pada bagian tertentu, maka cukup melakukannya pada component yang terkait.

Ohya, jika kamu bingung dalam menyatukan potongan code diatas, kamu dapat mengintip code lengkapnya di github. Ingat!, berusahalah terlebih dahulu untuk memahami tiap potongan code tersebut.

Category:
Share:

Comments