IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

tails

Vue JS 3 - Utilisation de propriétés calculées dans le css d'un composant

Noter ce billet
par , 01/09/2021 à 12h15 (315 Affichages)
Bonjour

Un besoin que je rencontre de temps en temps lorsque je code mes composants VueJS, c'est celui de générer des styles css dynamiquement. L'une des possibilités réside dans l'utilisation de variables css. Mais comment s'y prendre ?

Tout d'abord, dans ce billet j'utilise VueJS 3 ainsi que la nouvelle API Composition de VueJS. C'est-à-dire qu'au lieu d'utiliser les champs data, mounted, computed..., j'utilise le champ setup ainsi que les nouvelles fonctions mises en place (onMounted, ref, computed, watch, ...).

Afin d'illustrer le concept, je pars du principe que l'on souhaite créer un simple composant carré (MyBox) de couleur rouge, dont la taille est configurable via un attribut personnalisé sizePx.

Admettons pour l'instant que le composant dispose d'une taille fixe de 60px :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
  <div id="root"></div>
</template>

<script>
export default {
  name: 'MyBox',
  props: {
    
  }
}
</script>

<style scoped>
#root {
  width: 60px;
  height: 60px;
  background-color: red;
}
</style>
Rien de bien compliqué en soi.

Ajoutons la propriété sizePx (lignes 8-12), qui n'aura pas encore d'effet sur la taille de notre composant :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<template>
  <div id="root"></div>
</template>

<script>
export default {
  name: 'MyBox',
  props: {
    sizePx: {
      type: Number,
      required: true,
    }
  }
}
</script>

<style scoped>
#root {
  width: 60px;
  height: 60px;
  background-color: red;
}
</style>
On pourra, moyennant importation et déclaration du composant, l'utiliser de la manière suivante : <MyBox :sizePx="100" />A l'heure où ce billet a été rédigé, il existait une proposition de syntaxe afin de pouvoir injecter des variables de notre script du composant dans le css du même composant :
  1. la variable en question doit être une référence
  2. dans le css en question, la variable est référencée à l'aide de la fonction v-bind


Il est fort probable que votre éditeur en ligne favori (par exemple, j'ai testé avec StackBlitz), ne supporte pas cette syntaxe : mieux vaut créer un projet avec Vue CLI (c'est-à-dire avec le générateur de projet Vue JS depuis le terminal).

Voici ce que cela peut donner avec notre composant :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
<template>
  <div id="root"></div>
</template>

<script>
import  {computed} from 'vue';
export default {
  name: 'MyBox',
  props: {
    sizePx: {
      type: Number,
      required: true,
    }
  },
  setup(props) {
    const size = computed(() => props.sizePx + 'px');

    return {size};
  },
}
</script>

<style scoped>
#root {
  background-color: red;
  width: v-bind(size);
  height: v-bind(size);
}
</style>
Cette fois-ci, notre carré prend la dimension que l'on lui a indiqué.

Pour cela :
  1. j'ai crée une variable size, liée à la propriété sizePx (ligne 16)
  2. je l'ai référencée dans le css à l'aide de la fonction v-bind (lignes 26-27)


Ici, j'ai donné à la variable size la valeur de sizePx avec l'unité Mais je peux aussi ne donner que la valeur et ajouter l'unité lors de l'appel à la fonction v-bind dans le css :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
<template>
  <div id="root"></div>
</template>

<script>
import  {computed} from 'vue';
export default {
  name: 'MyBox',
  props: {
    sizePx: {
      type: Number,
      required: true,
    }
  },
  setup(props) {
    const size = computed(() => props.sizePx);

    return {size};
  },
}
</script>

<style scoped>
#root {
  background-color: red;
  width: calc(v-bind(size) * 1px);
  height: calc(v-bind(size) * 1px);
}
</style>
Vous pouvez remarquer:
  1. l'appel à la fonction calc
  2. la multiplication de la valeur par l'unité 1px


Rien nous empêche de changer d'unité : je peux aussi écrire width: calc(v-bind(size) * 0.2vw);,width: calc(v-bind(size) * 3px); ...

Enfin, j'ai eu besoin dans un de mes projets d'une utilisation plus complexe :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
37
<script>
import { ref, onMounted, onBeforeUnmount } from "vue";

export default {
   setup() {

      const controlsWidth = ref(0);
      const cellsSize = ref(0);

      function adjustLayoutDirection() {
          ...
          controlsWidth.value = isPortrait ? cellsSize.value * 8 + "px" : "calc(100% - " + cellsSize.value * 8 + "px)";
       }

      onMounted(() => adjustLayoutDirection);
      window.addEventListener("orientationchange", adjustLayoutDirection);
      onBeforeUnmount(function () {
         window.removeEventListener("orientationchange", adjustLayoutDirection);
       });

      return {
          controlsWidth, cellsSize
       };
   }
}
</script>

<style scoped>
#controls {
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  align-items: center;
  width: v-bind("controlsWidth");
}
</style>
Ainsi le calcul de la valeur controlsWidth (ligne 12) est très dynamique : notamment avec l'intégration de la fonction calc dans la chaîne résultante en orientation paysage.

Voilà, j'espère avoir bien présenté le concept. N'hésitez pas à aller voir la page de la proposition de syntaxe, et à expérimenter cette fonctionnalité.

Envoyer le billet « Vue JS 3 - Utilisation de propriétés calculées dans le css d'un composant » dans le blog Viadeo Envoyer le billet « Vue JS 3 - Utilisation de propriétés calculées dans le css d'un composant » dans le blog Twitter Envoyer le billet « Vue JS 3 - Utilisation de propriétés calculées dans le css d'un composant » dans le blog Google Envoyer le billet « Vue JS 3 - Utilisation de propriétés calculées dans le css d'un composant » dans le blog Facebook Envoyer le billet « Vue JS 3 - Utilisation de propriétés calculées dans le css d'un composant » dans le blog Digg Envoyer le billet « Vue JS 3 - Utilisation de propriétés calculées dans le css d'un composant » dans le blog Delicious Envoyer le billet « Vue JS 3 - Utilisation de propriétés calculées dans le css d'un composant » dans le blog MySpace Envoyer le billet « Vue JS 3 - Utilisation de propriétés calculées dans le css d'un composant » dans le blog Yahoo

Commentaires