Introduction à petite-vue

Publié le 3 septembre 2021 par Victor Darras | javascript

Cet article est publié sous licence CC BY-NC-SA

Bonjour à tous, aujourd’hui un court article autour d’une petite nouveauté que nous délivre le créateur de VueJS. Nous allons découvrir (ou redécouvrir) ensemble une bibliothèque simple mais efficace inspirée du framework bien connu. À l’instar de VueJS, petite-vue nous permet de dynamiser des pages avec JavaScript pour en améliorer l’UX et la réactivité. Mais cette dernière se veut surtout plus légère, et s’oriente plutôt vers l’amélioration progressive de vos pages web comme pouvaient l’être jQuery ou Alpine ; elle ne requiert pas de build particulier et peut être importée avec une simple balise <script>.

En bref, petite-vue est une bibliothèque de moins de 5kb, développée par le créateur de VueJS et reprend dans les grandes lignes sa syntaxe et sa réactivité. Le projet n’en est encore qu’à ses balbutiements, mais plaira sans nul doute aux amateurs de VueJS (dont je fais partie).

Installation de la bibliothèque

Pour la simplicité de cet article, je vous invite à charger petite-vue depuis un CDN ; il ne tient qu’à vous de la servir avec le reste du contenu de votre site pour la postérité.

<script src="https://unpkg.com/petite-vue" defer init></script>

Comme pour n’importe quel script, l’attribut defer s’assurera de charger la source une fois l’ensemble du HTML interprété. L’attribut init quant à lui est spécifique à petite-vue et s’assure de l’initialiser une fois chargée. Pour notre exercice d’aujourd’hui, je vous montrerai comment initialiser un semblant de données, ce que nous ferons avant de monter notre « application », nous n’aurons donc pas besoin d’init.

Mise en place des données

Pour cet article, j’ai voulu mettre en place un exercice rapide pour prendre en main quelques méthodes basiques ; il s’agira d’un générateur de box-shadow unique.

Une fois chargé, commençons donc à construire une app simple avec createApp qui prend en argument un ensemble de données, et un getter, que nous utiliserons à la manière d’une computed. Nous aurons aussi une méthode copyToClipboard, que je détaillerai un peu en fin d’article et n’est pas liée au fonctionnement de petite-vue.

PetiteVue.createApp({
  inset: false,
  x: 5,
  y: 5,
  blur: 25,
  spread: 0,
  color: "#00000055",
  copyText: "Copy",

  get inlineStyle (){
    return `
    box-shadow: ${ this.inset ? 'inset' : '' } ${ this.x }px ${ this.y }px ${ this.blur }px ${ this.spread }px ${ this.color };
    `;
  },

  copyToClipboard() {
    /* … */
  }
}).mount()

On relie tous les fils ensemble

Passons maintenant au contenu HTML, nous allons avoir besoin d’un formulaire avec un champ pour chaque attribut de la future box-shadow :

<form>
  <label for="inset">
    <input id="inset" type="checkbox" v-model="inset">
    &nbsp;Inset ?
  </label>

  <label for="offsetX">Offset X</label>
  <input id="offsetX" min="0" max="100" type="range" v-model="x">

  <label for="offsetY">Offset Y</label>
  <input id="offsetY" min="0" max="100" type="range" v-model="y">

  <label for="blur">Blur</label>
  <input id="blur" type="range" v-model="blur">

  <label for="spread">Spread</label>
  <input id="spread" type="range" v-model="spread">

  <label for="color">Color</label>
  <input id="color" type="text" v-model="color">
</form>

Comme avec VueJS, nous pouvons mettre des attributs v-model sur chaque input qui pointent vers les data définies précédemment.

Qu’est-ce que ça donne ?

Nous avons aussi besoin d’afficher le résultat de notre formulaire, en l’occurrence le style généré à la volée. On peut utiliser un attribut v-if qui conditionnera l’affichage de la balise sur laquelle il est appliqué. Pour afficher les données, on utilisera (encore une fois) la même syntaxe que VueJS, soit les doubles accolade :

<h2 class="result">
  <span v-if="inset">inset</span>
  <span>px</span>
  <span>px</span>
  <span v-if="blur !== 0">px</span>
  <span v-if="spread !== 0">px</span>
  <span v-if="color"></span>
</h2>

Le rendu visuel

Afin de donner un peu de corps à notre générateur de box-shadow je vous propose de l’appliquer à la volée sur notre formulaire. Contrairement à VueJS, il n’y a pas la possibilité d’ajouter un attribut v-bind:style (pour le moment peut-être ?); Il va nous falloir ruser, et je vous propose d’ajouter une balise <style> dans laquelle on pourra appeler la méthode inlineStyle :

<style>
  form { </button>

Le contenu du bouton est dynamique, et défini dans nos data côté JavaScript. À chaque modification des données ; je vais vouloir redéfinir le contenu du bouton, je peux donc ajouter un événement change sur le formulaire :

<form @change="copyText = 'Copy'" >

Revenons rapidement à notre JavaScript pour mettre en place la fonction de copie dans le presse-papier :

copyToClipboard() {
  const el = document.createElement('textarea');
  el.value = this.inlineStyle.trim();
  el.setAttribute('readonly', '');
  el.style.position = 'absolute';
  el.style.left = '-9999px';
  document.body.appendChild(el);
  el.select();
  document.execCommand("copy");
  document.body.removeChild(el);
  this.copyText = "copied";
}

Aperçu du résultat final !

Si tout se passe bien de votre côté (et je l’espère), en ajoutant quelques lignes de CSS vous devriez obtenir quelque chose qui ressemble à cet exemple sur CodePen :

Conclusion

J’ai vraiment apprécié petite-vue pour ce petit exercice, la mise en place est rapide, la prise en main pour un utilisateur de VueJS est instantanée ; je n’ai fait que peu d’allers-retours dans la doc et j’arrive à un résultat intéressant en très peu de temps. Je n’ai évidemment pas abordé l’ensemble des possibilités de la bibliothèque, notamment la notion de scope par élément de DOM (puisque ici tout le document était dynamique) qui me parait essentiel pour ce genre d’usage ; mais ça fera peut-être l’objet d’un futur article ! Sachez en tout cas que bon nombre des fonctionnalités de VueJS sont retrouvables avec petite-vue et que l’ensemble des différences sont présentées clairement sur le README du dépôt.

J’espère vous avoir donné un bon aperçu de ce que pouvait offrir cette mouture de VueJS orientée progressive enhancement et si tel est le cas, je vous invite à partager cet article autour de vous.


L’équipe Synbioz.
Libres d’être ensemble.