Setelah mengetahui dasar pembuatan komponen, sekarang kita akan belajar cara komunikasi komponen pada Vue.js dengan props dan $emit agar node parent dan node child dapat saling berinteraksi. Vue menyediakan fasilitas props yang berfungsi untuk meneruskan data dari parent ke child dan $emit untuk mengirim custom event dari child ke parent.

Buat file latihan009.html, lalu copy paste baris kode berikut :

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Latihan Vue 009</title>
    <link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
    <div id="app">
        <div class="jumbotron text-center">
            <h1>Bootstrap 4</h1>
            <p>Latihan009 - Komunikasi Komponen Pada Vue.js</p>
        </div>
        <div class="container">
            <div class="row">
                Selamat Datang di VarianCode.com
            </div>
        </div>
    </div>
</body>
</html>

Catatan : mulai materi ini, seluruh contoh yang saya berikan berikutnya akan menggunakan Bootstrap 4, salah satu framework CSS yang sangat pupuler dan telah digunakan oleh jutaan website saat ini. Dengan Bootstrap, kita bisa membangun aplikasi web yang responsive (mobile-ready) dengan lebih mudah dan memiliki desain yang menarik.

Agar CSS Bootstrap dapat digunakan, Anda harus terlebih dahulu mengintegrasikannya ke dalam halaman HTML. Untuk latihan ini, file bootstrap.min.css saya unduh dari https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css

komunikasi komponen pada vue.js dengan props dan $emit

Panduan lengkap penggunaan Bootstrap 4 sangat mudah ditemukan di internet dan sudah banyak website yang membahasnya, tapi salah satu favorit saya adalah : W3schools Bootstrap 4 Tutorial. Untuk sementara, hasil yang kita peroleh dari eksekusi latihan009.html adalah :

komunikasi komponen pada vue.js dengan props dan $emit

Meneruskan Data dari Parent ke Child dengan props

Sekarang kita akan melakukan beberapa penambahan baris kode pada file latihan009.html seperti berikut :

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Latihan Vue 009</title>
    <link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
    <div id="app">
        <div class="jumbotron text-center">
            <h1>Bootstrap 4</h1>
            <p>Latihan009 - Komunikasi Komponen Pada Vue.js</p>
          </div>
        <div class="container">
            <div class="row">
                <div class="col-md-6">
                    <pesan-alert jenis-alert="success" pesan="Selamat datang di vue.js"></pesan-alert>
                </div>
                <div class="col-md-6">
                    <pesan-alert jenis-alert="warning" pesan="Belajar vue.js menyenangkan"></pesan-alert>
                </div>
            </div>
        </div>
    </div>
    <script src="vue.js"></script>
    <script src="latihan009.js"></script>
</body>
</html>

dan juga buat file latihan009.js lalu copy paste kode di bawah ini :

Vue.component('PesanAlert', {
    props: ['jenisAlert', 'pesan'],
    template: `
        <div :class="classAlert">
            {{ pesan }}
        </div>
    `,
    computed: {

        classAlert() {
            return 'alert ' + 'alert-' + this.jenisAlert + ' alert-dismissible';
        }

    }
});

new Vue ({    
    el: '#app'
});

Pada kode di atas, saya hanya memiliki satu komponen tunggal, yaitu PesanAlert yang diakses melalui elemen <pesan-alert></pesan-alert>. Kerena PesanAlert tidak memiliki komponen parent maupun child, maka secara otomatis komponen ini menjadi child dari node parent <div id="app">.

Node <div id="app"> meneruskan data jenis-alert dan pesan ke komponen PesanAlert :

<pesan-alert jenis-alert="success" pesan="Selamat datang di vue.js"></pesan-alert>
<pesan-alert jenis-alert="warning" pesan="Belajar vue.js menyenangkan"></pesan-alert>

Nilai data jenis-alert dan pesan diterima oleh node child (komponen PesanAlert) melalui baris kode :

props: ['jenisAlert', 'pesan'],

Catatan : penamaan props di sisi Vue umumnya ditulis dengan gaya camelCase (jenisAlert), sedangkan di sisi HTML wajib ditulis dengan kebab-case (jenis-alert). Khusus di option template, property pada props dapat diakses tanpa keyword this.

Property pesan digunakan di expression {{pesan}}, sedangkan jenisAlert diproses di option computed melalui fungsi classAlert() dan nilai return nya dikaitkan (class binding) ke elemen <div :class="classAlert">. Nilai return dari fungsi classAlert() masing-masing adalah alert alert-success alert-dismissible (hijau muda) dan alert alert-warning alert-dismissible (kuning muda).

komunikasi komponen pada vue.js dengan props dan $emit

Mengirim Custom Event dari Child ke Parent dengan $emit

Untuk contoh selanjutnya, saya menambahkan custom event bernama kliksilang. Ketika button bertanda silang di-klik, komponen PesanAlert akan mengirim custom event ke parent (node di atasnya) melalui $emit. Dari sini parent dapat mengetahui bahwa telah terjadi event di child.

Perbarui file latihan009.html dengan beris kode berikut :

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Latihan Vue 009</title>
    <link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
    <div id="app">
        <div class="jumbotron text-center">
            <h1>Bootstrap 4</h1>
            <p>Latihan009 - Komunikasi Komponen Pada Vue.js</p>
          </div>
        <div class="container">
            <div class="row">
                <div class="col-md-6">
                    <pesan-alert 
                        jenis-alert="success"
                        pesan="Selamat datang di vue.js"
                        @kliksilang="munculkanPopup"
                    ></pesan-alert>
                </div>
                <div class="col-md-6">
                    <pesan-alert 
                        jenis-alert="warning" 
                        pesan="Belajar vue.js menyenangkan"
                        @kliksilang="munculkanPopup" 
                    ></pesan-alert>
                </div>
            </div>
        </div>
    </div>
    <script src="vue.js"></script>
    <script src="latihan009.js"></script>
</body>
</html>

dan juga file latihan009.js menjadi :

Vue.component('PesanAlert', {
    props: ['jenisAlert', 'pesan'],
    template: `
        <div :class="classAlert">
            <button type="button" class="close" @click="$emit('kliksilang', pesan)">&times;</button>
            {{ pesan }}
        </div>
    `,
    computed: {
        classAlert() {
            return 'alert ' + 'alert-' + this.jenisAlert + ' alert-dismissible';
        }
    }
});

new Vue ({    
    el: '#app',
    methods: {
        munculkanPopup(pesan) {
            alert('Popup dari ' + pesan)
        }
    }
});

Urutan cara membaca kode di atas adalah :

  1. Komponen PesanAlert melakukan listening event berupa klik button melalui directive @click="$emit('kliksilang', pesan)".
  2. Argumen pertama kliksilang pada $emit adalah custom event yang akan dikirim ke node parent <div id="app">.
  3. Node parent <div id="app"> menerima event kliksilang dari komponen <pesan-alert> melalui directive @kliksilang="munculkanPopup".
  4. Ketika event dari child diterima parent, method munculkanPopup pada directive @kliksilang="munculkanPopup" akan dieksekusi.
  5. Argumen untuk parameter pesan yang ada di munculkanPopup(pesan) diperoleh dari $emit('kliksilang', pesan) sebelumnya.

Hasil eksekusi file latihan009.html :

komunikasi komponen pada vue.js dengan props dan $emit