Comme mentionné par Chris Fritz (Vue.js Core Team Emeriti ) dans VueCONF US 2019
si Kia entre .native
et que l'élément racine de l'entrée de base est passé d'une entrée à une étiquette, ce composant est soudainement cassé et ce n'est pas évident et en fait, vous pourriez même ne pas l'attraper tout de suite à moins d'avoir un très bon test. Au lieu de cela, en évitant l'utilisation du .native
modificateur que je considère actuellement comme un anti-modèle sera supprimé dans Vue 3, vous pourrez définir explicitement que le parent pourrait se soucier de l'élément auquel les écouteurs sont ajoutés ...
Avec Vue 2
En utilisant $listeners
:
Donc, si vous utilisez Vue 2, une meilleure option pour résoudre ce problème serait d'utiliser une logique de wrapper entièrement transparente . Pour cela, Vue fournit une $listeners
propriété contenant un objet d'écouteurs utilisés sur le composant. Par exemple:
{
focus: function (event) { /* ... */ }
input: function (value) { /* ... */ },
}
et puis nous avons juste besoin d'ajouter v-on="$listeners"
au test
composant comme:
Test.vue (composant enfant)
<template>
<div v-on="$listeners">
click here
</div>
</template>
Maintenant, le <test>
composant est un wrapper totalement transparent , ce qui signifie qu'il peut être utilisé exactement comme un <div>
élément normal : tous les écouteurs fonctionneront, sans le .native
modificateur.
Démo:
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>
En utilisant la $emit
méthode:
Nous pouvons également utiliser la $emit
méthode à cet effet, qui nous aide à écouter les événements des composants enfants dans le composant parent. Pour cela, nous devons d'abord émettre un événement personnalisé à partir du composant enfant comme:
Test.vue (composant enfant)
<test @click="$emit('my-event')"></test>
Important: utilisez toujours kebab-case pour les noms d'événements. Pour plus d'informations et une démonstration de ce point, veuillez consulter cette réponse: VueJS passant la valeur calculée du composant au parent .
Maintenant, nous avons juste besoin d'écouter cet événement personnalisé émis dans le composant parent comme:
App.vue
<test @my-event="testFunction"></test>
Donc, fondamentalement, au lieu de v-on:click
ou de la sténographie, @click
nous utiliserons simplement v-on:my-event
ou simplement @my-event
.
Démo:
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>
Avec Vue 3
Utilisationv-bind="$attrs"
:
Vue 3 va nous faciliter la vie à bien des égards. L'un des exemples est qu'il nous aidera à créer un wrapper transparent plus simple avec très moins de configuration en utilisant simplement v-bind="$attrs"
. En utilisant ceci sur les composants enfants, non seulement notre écouteur fonctionnera directement à partir du parent, mais aussi tout autre attribut fonctionnera également comme s'il était normal<div>
.
Donc, en ce qui concerne cette question, nous n'aurons pas besoin de mettre à jour quoi que ce soit dans Vue 3 et votre code fonctionnera toujours correctement, tout comme <div>
l'élément racine ici et il écoutera automatiquement tous les événements enfants.
Démo n ° 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>
Mais pour les composants complexes avec des éléments imbriqués où nous devons appliquer des attributs et des événements à main <input />
au lieu de l'étiquette parent, nous pouvons simplement utiliserv-bind="$attrs"
Démo n ° 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"