Menu contextuel personnalisé VueJs
Vous avez souvent du voir des menus contextuels personnalisés qui apparaissent lorsque vous faites un clic droit par exemple dans vos messageries web.
Le clic droit étant exécuté côté client, il faut du code client pour modifier le comportement de ce clic, donc du javascript donc VueJs peut lui aussi gérer l’affichage d’un menu contextuel personnalisé.
Après quelques recherches et tests, le plus simple pour gérer cela, c’est d’utiliser une librairie VueJs : vue-simple-context-menu me semble la librairie la plus simple à utiliser et elle fait très bien le job. Voici comment cela fonctionne
Installation
Si vous avez suivi mon tuto sur l’environnement de développement (formation gratuite proposée ci-dessous), vous aurez vu que je conseille souvent d’utiliser les packages NPM s’ils sont disponibles. C’est le cas pour cette librairie. Du coup, simple commande dans la console POWERSHELL pour installer le package :
npm install vue-simple-context-menu
Maintenant que vous avez installé le package, il vous reste à demander à Vue de l’ajouter dans les composants à utiliser. Pour se faire, allez dans votre fichier App.js et ajouter ceci:
import VueSimpleContextMenu from 'vue-simple-context-menu'
import 'vue-simple-context-menu/dist/vue-simple-context-menu.css'
...
Vue.component('vue-simple-context-menu', VueSimpleContextMenu)
...
Vous pouvez voir 3 choses :
- On importe notre composant depuis le package pour pouvoir l’utiliser dans VueJs : ça c’est comme d’habitude.
- Par contre, on importe également le CSS depuis le package car on en a besoin pour que le menu contextuel s’affiche sous forme d’un menu. Sans cela, votre menu va s’afficher sans même avoir fait de clic droit et en plus il va s’afficher à la suite de votre page html directement.
- Enfin, on utilise le composant sous le nom “vue-simple-context-menu”. C’est ce nom qui sera utilisé dans les balises de notre template dans App.vue.
Utilisation
Voilà, tout est installé et prêt à être utilisé. Pour afficher un menu contextuel, on va s’abonner à un événement : @contextmenu. Et pour éviter que cet événement déclenche l’ouverture du menu contextuel habituel, on va s’abonner à @contextmenu.prevent.stop. Voici ce que ça donne si on fait une DIV “Cliquez ici” et qu’on s’abonne à sont événement clic-droit dans notre temple (fichier App.vue):
<template>
<div id="app">
<div @contextmenu.prevent.stop="handleClick($event, 'CliquezIci')">Cliquez ici</div>
</div>
</template>
Alors, on a notre DIV avec le texte “Cliquez ici” et on s’abonne à l’événement @contextmenu.prevent.stop qui attérit sur une méthode “handleClick(event, item)”. J’ai mis ‘CliquezIci’ dans le handleClick afin de savoir sur quel objet j’ai cliqué. En effet, quand vous cliquez sur un élément, il est bien de savoir sur quel élément vous avez cliqué même si dans notre exemple, on a juste un élément DIV.
Bon maintenant, créons dans ce TEMPLATE notre menu contextuel:
<template>
<div id="app">
<div @contextmenu.prevent.stop="handleClick($event, 'Cliquez ici')">Cliquez ici</div>
<vue-simple-context-menu
:elementId="'UniqueId'"
:options="menuItems"
:ref="'vueSimpleContextMenu1'"
@option-clicked="onClick"
>
</vue-simple-context-menu>
</div>
</template>
Vous pouvez voir le menu dans la balise <vue-simple-context-menu…>. Il y a différents attributs :
- elementId: c’est un ID unique pour l’élément. Attention, comme c’est une chaîne de caractère et pas un nom de variable qui pointe vers une DATA de VueJs, il faut bien mettre entre ” et ‘.
- options: c’est la liste de nos menus que nous verrons plus bas. Dans ce cas, comme on pointe vers une DATA de VueJs, on met juste des “.
- ref: c’est le nom du menu contextuel qui sera utilisé pour l’afficher dans notre méthode handleClick. Là encore comme c’est un nom et pas une DATA, on met entre ” et ‘.
- @option-clicked permet de s’abonner au click sur l’un de nos menus dans le menu contextuel. Ici, on redirige le click vers une méthode VueJs “onClick”.
Passons à la partie données (DATA):
data() {
return {
menuItems: [
{
name: 'Menu1',
slug: 'menu1'
}
]
}
}
Rien de bien incroyable, on a simplement nos menus qui apparaîtrons dans notre menu contextuel : il s’agit d’un ARRAY (tableau) de menu. Chaque menu doit contenir une propriété “name” qui sera affichée. Vous êtes libre après d’ajouter toutes les propriétés que vous souhaitez à chaque menu mais il faut absolument cette propriété “name”.
Passons maintenant à nos méthodes :
methods: {
handleClick(event, item) {
this.$refs.vueSimpleContextMenu1.showMenu(event, item)
},
onClick(event) {
window.alert("item: "+event.item+" - menu: "+event.option.name);
}
}
- Le handleClick nous permet de savoir quand il y a un clic droit sur un élément et donc va déclencher l’ouverture du menu contextuel. On voit bien qu’on appelle notre menu avec le nom qu’on lui a donné dans sa propriété “ref”. Ici, on va donc la rechercher dans this.$refs.{nom du menu dans ref}.showMenu(event, item). Le showMenu permet d’afficher le menu. On lui passe l’événement de la souris (il faut que ce soit un MouseEvent car c’est cet événement qu’il utilise pour positionner le menu contextuel. Ensuite, on lui passe l’item sur lequel on a cliqué afin qu’il garde une trace de l’item sur lequel on a cliqué pour nous pour plus tard. Cela peut être un libellé, un nom, ou même un objet.
- Le onClick quant à lui nous indique que l’utilisateur a cliqué sur l’un des menus de notre menu contextuel. On reçoit en paramètre un objet contenant notre item (event.item) et notre menu sur lequel l’utilisateur a cliqué (event.menu). Si on veut accéder au nom du menu sur lequel il a cliqué, rien de plus simple : event.menu.name.
Conclusion
Voilà, vous avez vu que l’abonnement au clic droit est assez simple de même que l’affichage d’un menu contextuel lorsqu’on a les bonnes informations et qu’on utilise des librairies qui existent toutes faites. Je vous avouerais que j’ai eu plusieurs problèmes avant de réussir à faire fonctionner cette librairie c’est pourquoi je vous partage ce petit tuto.
J’espère qu’il vous aura plu. N’hésitez pas à commenter, partager et même à vous abonner à ce blog pour ne rien rater.
A bientôt sur développement-web-facile.com.