projet [vuejs-09] : utilisation d’un plugin [eventBus]¶
Le projet [vuejs-09] est identique au projet [vuejs-08] si ce n’est qu’il introduit la notion de plugin. L’arborescence du projet est la suivante :
Le plugin [./plugins/event-bus]¶
Le script [./event-bus.js] reste ce qu’il était dans l’exemple précédent :
1 2 3 | import Vue from 'vue';
const eventBus = new Vue();
export default eventBus;
|
Le plugin [./plugins/event-bus.js] est le suivant :
1 2 3 4 5 6 7 8 9 | export default {
install(Vue, eventBus) {
// ajoute une propriété [$eventBus] à la classe Vue
Object.defineProperty(Vue.prototype, '$eventBus', {
// lorsque Vue.$eventBus est référencé, on rend le 2ième paramètre [eventBus]
get: () => eventBus,
})
}
}
|
Commentaires
- un plugin [Vue] est un objet ayant une fonction [install] (ligne 2). Celle-ci sera automatiquement appelée lorsqu’un code déclare l’utilisation du plugin ;
- lignes 1-9 : l’objet exporté par le script ;
- ligne 2 : la fonction [install] accepte ici deux paramètres :
- [Vue] : la fonction obtenue par l’instruction [import Vue from ‘Vue’]. Peut-être assimilée à une classe ;
- [eventBus] : l’objet exporté par le script [./event-bus] ;
- lignes 4-7 : modifient la définition (on dit le prototype) de la fonction [Vue] en lui ajoutant la propriété [$eventBus]. Si on raisonne avec le terme [classe], la propriété [$eventBus] est ajoutée à la clase [Vue]. Les composants qui sont des instances de [Vue] auront donc accès à cette nouvelle propriété ;
- la ligne 6 indique que lorsqu’on référencera la propriété [Vue].$eventBus, on obtiendra le paramètre [eventBus] de la ligne 2. Nous allons voir un peu plus loin que ce second paramètre sera l’objet [eventBus] exporté par le script [./event-bus.js]. Donc au final, lorsqu’un composant C utilisera l’expression [C.$eventBus] il référencera l’objet [eventBus] exporté par le script [./event-bus.js]. Cela lui évitera d’importer le script [./event-bus.js]. L’intérêt du plugin est là : simplifier l’accès à l’objet [eventBus] exporté par le script [./event-bus.js] ;
- on notera que le plugin n’a pas à s’appeler lui-même [event-bus.js]. On aurait pu l’appeler [plugin-event-bus] par exemple ;
- on notera également que le terme $ dans [$eventBus] est une convention pour désigner les propriétés de [Vue] qui ont été ajoutées via des plugins. On n’est pas obligés d’observer cette convention. Dans ce texte, nous l’observerons ;
Le script principal [main.js]¶
Le script [./plugins/event-bus.js] définit un plugin pour le framework [Vue.js]. Ce plugin n’est pas encore utilisé, juste défini. C’est le script [main.js] qui l’active :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // imports
import Vue from 'vue'
import App from './App.vue'
// plugins
import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue);
// bootstrap
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
// eventbus
import eventBus from './event-bus';
import PluginEventBus from './plugins/event-bus';
Vue.use(PluginEventBus, eventBus);
// configuration
Vue.config.productionTip = false
// instanciation projet [App]
new Vue({
render: h => h(App),
}).$mount('#app')
|
Commentaires
- les lignes 14-16 activent le plugin [PluginEventBus]. Après la ligne 16, toutes les instances de la classe (fonction) [Vue] possèdent la propriété [$eventBus] qui pointe pour chacune d’elles sur le même object exporté par le script [./event-bus.js]. Ce sera le cas pour chacun des composants du projet ;
La vue principale [App]¶
La vue principale [App] reste ce qu’elle était dans le projet précédent.
Le composant [Component1]¶
Le composant [Component1] utilise désormais sa propriété [$eventBus] pour écouter l’événement [someEvent] :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <template>
<b-row>
<b-col>
<b-alert show
variant="warning"
v-if="showMsg">Evénement [someEvent] intercepté par [Component1]. Valeur reçue={{data}}</b-alert>
</b-col>
</b-row>
</template>
<script>
export default {
name: "component1",
// état du composant
data() {
return {
data: "",
showMsg: false
};
},
// méthodes de gestion des évts
methods: {
// gestion de l'evt [someEvent]
doSomething(data) {
this.data = data;
this.showMsg = true;
}
},
// gestion du cycle de vie du composant
// évt [created] - le composant a été créé
created() {
// écoute de l'évt [someEvent]
this.$eventBus.$on("someEvent", this.doSomething);
}
};
</script>
|
Commentaires
- ligne 33, utilisation de la propriété [this.$eventBus] du composant. On remarquera de plus que le script ligne 11 n’importe plus le script [./event-bus.js] ;
Le composant [Component2]¶
Le composant [Component2] utilise désormais sa propriété [$eventBus] pour émettre l’événement [someEvent] :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <template>
<div>
<b-button @click="createEvent">Créer un événement</b-button>
</div>
</template>
<!-- script -->
<script>
export default {
name: "component2",
// méthodes de gestion des évts
methods: {
createEvent() {
this.$eventBus.$emit("someEvent", { x: 2, y: 4 })
}
}
};
</script>
|
Commentaires
- ligne 13, utilisation de la propriété [this.$eventBus] du composant. On remarquera de plus que le script ligne 7 n’importe plus le script [./event-bus.js] ;
Composant [Component3]¶
Le composant [Component3] a le même code que [Component1]. Lui également écoute l’événement [someEvent].