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:
-
Creating & Registering Component
-
Make form validation
-
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
.
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:
-
Mengubah value dari
button
menjadi true. -
Mengecek, jika value dari
show
adalah biodata dan value darivalName
danvalEmail
tidak bernilai true maka akan menjalan perintah yang ada didalam block if. -
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 mengenaithis.$refs.form
akan dibahas setelah ini. -
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>
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.
Comments