Seperti yang disebutkan oleh Chris Fritz (Vue.js Core Team Emeriti ) di VueCONF US 2019
jika kita memiliki Kia masuk .native
dan kemudian elemen root dari input dasar berubah dari input ke label tiba-tiba komponen ini rusak dan itu tidak jelas dan pada kenyataannya, Anda bahkan mungkin tidak langsung menangkapnya kecuali Anda memiliki tes yang sangat bagus. Alih-alih dengan menghindari penggunaan .native
pengubah yang saat ini saya anggap sebagai anti-pola akan dihapus di Vue 3 Anda akan dapat secara eksplisit menentukan bahwa orang tua mungkin peduli tentang elemen pendengar yang ditambahkan ke ...
Dengan Vue 2
Menggunakan $listeners
:
Jadi, jika Anda menggunakan Vue 2 pilihan yang lebih baik untuk menyelesaikan masalah ini adalah dengan menggunakan logika wrapper yang sepenuhnya transparan . Untuk Vue ini menyediakan $listeners
properti yang berisi objek pendengar yang digunakan pada komponen. Sebagai contoh:
{
focus: function (event) { /* ... */ }
input: function (value) { /* ... */ },
}
dan kemudian kita hanya perlu menambahkan v-on="$listeners"
ke test
komponen seperti:
Test.vue (komponen anak)
<template>
<div v-on="$listeners">
click here
</div>
</template>
Sekarang <test>
komponennya adalah pembungkus yang sepenuhnya transparan , artinya dapat digunakan persis seperti <div>
elemen normal : semua pendengar akan bekerja, tanpa .native
pengubah.
Demo:
Vue.component('test', {
template: `
<div class="child" v-on="$listeners">
Click here
</div>`
})
new Vue({
el: "#myApp",
data: {},
methods: {
testFunction: function(event) {
console.log('test clicked')
}
}
})
div.child{border:5px dotted orange; padding:20px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="myApp">
<test @click="testFunction"></test>
</div>
Menggunakan $emit
metode:
Kita juga dapat menggunakan $emit
metode untuk tujuan ini, yang membantu kita mendengarkan peristiwa komponen anak dalam komponen induk. Untuk ini, pertama-tama kita harus memancarkan acara khusus dari komponen anak seperti:
Test.vue (komponen anak)
<test @click="$emit('my-event')"></test>
Penting: Selalu gunakan kotak kebab untuk nama acara. Untuk informasi lebih lanjut dan demo pembuatan ulang poin ini, silakan periksa jawaban ini: VueJS meneruskan nilai yang dihitung dari komponen ke induk .
Sekarang, kita hanya perlu mendengarkan acara kustom yang dipancarkan ini di komponen induk seperti:
Aplikasi
<test @my-event="testFunction"></test>
Jadi, pada dasarnya alih-alih v-on:click
atau singkatan @click
kami hanya akan menggunakan v-on:my-event
atau hanya @my-event
.
Demo:
Vue.component('test', {
template: `
<div class="child" @click="$emit('my-event')">
Click here
</div>`
})
new Vue({
el: "#myApp",
data: {},
methods: {
testFunction: function(event) {
console.log('test clicked')
}
}
})
div.child{border:5px dotted orange; padding:20px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="myApp">
<test @my-event="testFunction"></test>
</div>
Dengan Vue 3
Menggunakan v-bind="$attrs"
:
Vue 3 akan membuat hidup kita lebih mudah dalam banyak hal. Salah satu contoh untuk itu adalah itu akan membantu kita untuk membuat pembungkus transparan yang lebih sederhana dengan konfigurasi yang sangat sedikit hanya dengan menggunakan v-bind="$attrs"
. Dengan menggunakan ini pada komponen anak tidak hanya pendengar kita akan bekerja langsung dari orang tua tetapi juga atribut lain juga akan berfungsi seperti biasa<div>
saja.
Jadi, sehubungan dengan pertanyaan ini, kami tidak perlu memperbarui apa pun di Vue 3 dan kode Anda masih akan berfungsi dengan baik seperti <div>
elemen root di sini dan itu akan secara otomatis mendengarkan semua acara anak-anak.
Demo # 1:
const { createApp } = Vue;
const Test = {
template: `
<div class="child">
Click here
</div>`
};
const App = {
components: { Test },
setup() {
const testFunction = event => {
console.log("test clicked");
};
return { testFunction };
}
};
createApp(App).mount("#myApp");
div.child{border:5px dotted orange; padding:20px;}
<script src="//unpkg.com/vue@next"></script>
<div id="myApp">
<test v-on:click="testFunction"></test>
</div>
Tetapi untuk komponen yang kompleks dengan elemen bersarang di mana kita perlu menerapkan atribut dan acara ke utama <input />
alih-alih label induk kita cukup gunakanv-bind="$attrs"
Demo # 2:
const { createApp } = Vue;
const BaseInput = {
props: ['label', 'value'],
template: `
<label>
{{ label }}
<input v-bind="$attrs">
</label>`
};
const App = {
components: { BaseInput },
setup() {
const search = event => {
console.clear();
console.log("Searching...", event.target.value);
};
return { search };
}
};
createApp(App).mount("#myApp");
input{padding:8px;}
<script src="//unpkg.com/vue@next"></script>
<div id="myApp">
<base-input
label="Search: "
placeholder="Search"
@keyup="search">
</base-input><br/>
</div>
@click.native="testFunction"