Fermer

septembre 23, 2022

Utiliser des animations dans Vue.js


Voyons comment améliorer l’UX de votre application Vue avec des animations.

L’ajout d’animations à un site Web peut être un excellent moyen d’améliorer l’expérience utilisateur, car elles peuvent rendre les sites Web plus vivants et plus interactifs. Dans cet article, nous verrons comment créer des animations dans Vue.js—l’un des frameworks JavaScript les plus populaires pour la création d’interfaces utilisateur.

Vous pouvez trouver l’exemple de code complet dans ce dépôt GitHub. Ci-dessous, vous pouvez également trouver un exemple interactif CodeSandbox.

Configuration du projet

Nous allons utiliser Vite pour échafauder rapidement un nouveau projet Vue. Si vous n’avez jamais entendu parler de Vite auparavant, vous voudrez peut-être consulter mes articles à ce sujet : Qu’est-ce que Vite : le guide des outils de projet modernes et ultra-rapides.

Exécutez la commande ci-dessous dans votre terminal pour créer un nouveau projet Vue.

$ npm init vite vue-animations -- --template vue

Une fois la création du projet terminée, exécutez les commandes suivantes pour accéder au répertoire du projet et installer toutes les dépendances.

$ cd vue-animations && npm install

Enfin, vous pouvez démarrer le serveur de développement en exécutant le npm run dev commande. Vous devriez voir le projet en cours d’exécution lors de la visite localhost:3000 dans votre navigateur. Voilà pour la configuration.

Animations en vue

Il existe plusieurs façons d’ajouter des animations dans Vue.js. Nous pouvons utiliser JavaScript pur ou CSS pour cela. Cependant, Vue propose également deux composants spécialement conçus pour les animations :Transition et Transition-Group. Le premier peut être utilisé pour animer un seul élément, tandis que le second pour un groupe d’éléments. Voyons comment nous pouvons utiliser ces deux composants.

Animation de l’opacité et de la position

Le GIF ci-dessous montre l’animation que nous allons implémenter.

Animation de l'opacité et de la position

Dans le projet que nous venons d’échafauder, nous avons le App.vue composant avec un logo Vue et du texte. Utilisons le Transition composant pour animer l’opacité et la position de App contenu du composant.

src/App.vue

<script setup>
import { Transition } from "vue";
import HelloWorld from "./components/HelloWorld.vue";
</script>

<template>
  <Transition appear>
    <div>
      <img width="200" height="200" alt="Vue logo" src="https://www.telerik.com/blogs/./assets/logo.png" />
      <HelloWorld msg="Hello Vue 3 + Vite" />
    </div>
  </Transition>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

.v-enter-active,
.v-leave-active {
  transition: opacity 2s ease, transform 1s ease-in-out;
  transform: translateY(0px);
}

.v-enter-from,
.v-leave-to {
  opacity: 0;
  transform: translateY(100px);
}
</style>

La Transition les composants ne doivent avoir qu’un seul enfant. Dans cet exemple, nous passons le appear appui à la Transition car nous voulons que l’animation démarre immédiatement lorsque le composant est monté. Dans le style bloc, nous avons de nouvelles classes :

  • v-enter-active – l’état dans lequel un élément est animé en entrant
  • v-leave-active – l’état dans lequel un élément est animé en quittant
  • v-enter-from – l’état à partir duquel un élément entrera
  • v-leave-to – l’état dans lequel un élément partira pour

Ces classes sont utilisées par les Transition composant si le name prop n’a pas été passé. Cependant, cela signifie qu’ils seront utilisés par tous Transition Composants. Ce n’est pas le meilleur parce que si nous en avions un autre Transition composant ailleurs dans le code, les classes d’animation entreraient en collision. Résolvons ce problème en passant le name soutenir. Voici le code mis à jour.

src/App.vue

<script setup>
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
import { Transition } from "vue";
import HelloWorld from "./components/HelloWorld.vue";
</script>

<template>
  <Transition name="fade-slide" appear>
    <div>
      <img width="200" height="200" alt="Vue logo" src="https://www.telerik.com/blogs/./assets/logo.png" />
      <HelloWorld msg="Hello Vue 3 + Vite" />
    </div>
  </Transition>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

.fade-slide-enter-active,
.fade-slide-leave-active {
  transition: opacity 2s ease, transform 1s ease-in-out;
  transform: translateY(0px);
}

.fade-slide-enter-from,
.fade-slide-leave-to {
  opacity: 0;
  transform: translateY(100px);
}
</style>

La .v- préfixe est remplacé par la chaîne que nous avons transmise au name soutenir. Nous avons passé fade-slidedonc les noms de classe sont devenus .fade-slide-*.

Basculer les animations

Pour le moment, le contenu est animé une fois lorsqu’il entre, et il le reste. Cependant, il est possible de basculer les animations en modifiant la visibilité d’un élément enfant. Ajoutons un bouton et une référence pour contrôler la visibilité du div élément qui est un enfant direct de Transition composant.

src/App.vue

<script setup>
import { Transition, ref } from "vue";
import HelloWorld from "./components/HelloWorld.vue";
const show = ref(true);
</script>

<template>
  <button @click="show = !show">Toggle animation</button>
  <Transition name="fade-slide" appear>
    <div v-show="show">
      <img width="200" height="200" alt="Vue logo" src="https://www.telerik.com/blogs/./assets/logo.png" />
      <HelloWorld msg="Hello Vue 3 + Vite" />
    </div>
  </Transition>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

.fade-slide-enter-active,
.fade-slide-leave-active {
  transition: opacity 2s ease, transform 1s ease-in-out;
  transform: translateY(0px);
}

.fade-slide-enter-from,
.fade-slide-leave-to {
  opacity: 0;
  transform: translateY(100px);
}
</style>

Commencez à cliquer sur le Toggle animation bouton pour animer le contenu à l’intérieur et à l’extérieur. Le GIF ci-dessous montre à quoi il ressemble.

Basculer les animations

Il n’est pas rare d’utiliser la même animation à plusieurs endroits. Par conséquent, c’est une bonne idée de les extraire dans leurs propres composants pour garder les choses au SEC. Déplaçons le Transition composant et fade-slide classes dans un nouveau composant appelé FadeSlideTransition.

src/components/FadeSlideTransition.vue

<template>
  <div>
    <Transition name="fade-slide" appear>
      <slot />
    </Transition>
  </div>
</template>
<script setup>
import { Transition } from "vue";
</script>
<style scoped>
.fade-slide-enter-active,
.fade-slide-leave-active {
  transition: opacity 2s ease, transform 1s ease-in-out;
  transform: translateY(0px);
}

.fade-slide-enter-from,
.fade-slide-leave-to {
  opacity: 0;
  transform: translateY(100px);
}
</style>

Maintenant, nous pouvons mettre à jour le App composant pour utiliser notre composant nouvellement créé.

src/App.vue

<script setup>
import { ref } from "vue";
import HelloWorld from "./components/HelloWorld.vue";
import FadeSlideTransition from "./components/FadeSlideTransition.vue";
  
const show = ref(true);
</script>

<template>
  <button @click="show = !show">Toggle animation</button>
  <FadeSlideTransition>
    <div v-show="show">
      <img width="200" height="200" alt="Vue logo" src="https://www.telerik.com/blogs/./assets/logo.png" />
      <HelloWorld msg="Hello Vue 3 + Vite" />
    </div>
  </FadeSlideTransition>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

L’animation devrait fonctionner comme avant. La différence, cependant, est que maintenant nous pouvons facilement réutiliser le FadeSlideTransition composant.

Animer une liste d’éléments

Jusqu’à présent, nous avons expliqué comment animer un élément à l’aide de Transition composant. Vue fournit également le TransitionGroup composant qui peut être utilisé pour animer plusieurs éléments. Voici un exemple de la façon dont nous pouvons utiliser le TransitionGroup composant pour faire glisser des éléments dans une liste.

src/components/AnimatingList.vue

<template>
  <div>
    <div class="form-block">
      <label>Item name</label>
      <input type="text" v-model="itemName" />
      <button @click="addItem">Add item</button>
    </div>
    <div>
      <TransitionGroup name="slide" tag="ul" appear class="list">
        <li v-for="item of items" :key="item">
          {{ item }}
        </li>
      </TransitionGroup>
    </div>
  </div>
</template>
<script setup>
import { TransitionGroup, ref } from "vue";
const items = ref([]);
const itemName = ref("");
const addItem = () => {
  items.value.push(itemName.value);
  itemName.value = "";
};
</script>
<style scoped>
.form-block {
  display: inline-flex;
  align-items: flex-start;
  flex-direction: column;
  margin: 0 auto;
}

.form-block :is(label, input) {
  margin-bottom: 0.5rem;
}

.list {
  list-style-type: none;
  padding: 0;
}

.list li {
  margin-bottom: 0.5rem;
}

.slide-enter-active,
.slide-leave-active {
  transition: all 0.5s ease;
}
.slide-enter-from,
.slide-leave-to {
  opacity: 0;
  transform: translateX(30px);
}
</style>

La input Le champ est utilisé pour entrer le nom des nouveaux éléments, qui seront ajoutés à la liste. La TransitionGroup le composant reçoit slide comme valeur pour le name soutenir. Par conséquent, il utilisera le slide-enter-* et slide-leave-* Des classes. L’animation fera fondre et glisser les éléments depuis le côté droit.

Maintenant, ajoutons le AnimatingList composant dans le App.vue dossier.

src/App.vue

<script setup>
import { ref } from "vue";
import HelloWorld from "./components/HelloWorld.vue";
import FadeSlideTransition from "./components/FadeSlideTransition.vue";
import AnimatingList from "./components/AnimatingList.vue";

const show = ref(true);
</script>

<template>
  <AnimatingList />
  <button @click="show = !show">Toggle animation</button>
  <FadeSlideTransition>
    <div v-show="show">
      <img width="200" height="200" alt="Vue logo" src="https://www.telerik.com/blogs/./assets/logo.png" />
      <HelloWorld msg="Hello Vue 3 + Vite" />
    </div>
  </FadeSlideTransition>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Le GIF ci-dessous montre à quoi ressemble l’animation.

Transition de groupe

Animations pilotées par l’état

Nous avons utilisé le Transition et TransitionGroup composants pour créer des animations dans Vue. Cependant, nous ne devons pas nécessairement les utiliser. Nous pouvons en fait utiliser l’état réactif de Vue pour animer des éléments. Voici un exemple de la façon dont nous pouvons créer un cercle qui suivra le curseur.

src/components/StateDrivenAnimation.vue

<template>
  <div :class="$style.circle"></div>
</template>
<script setup>
import { ref, onUnmounted } from "vue";
const pos = ref({
  x: 0,
  y: 0,
});

const onMouseMove = e => {
  console.log("mousemove", e.clientX, e.clientY);
  pos.value.x = `${e.clientX}px`;
  pos.value.y = `${e.clientY}px`;
};

window.addEventListener("mousemove", onMouseMove, {
  passive: true,
});

onUnmounted(() => {
  window.removeEventListener("mousemove", onMouseMove);
});
</script>
<style module>
.circle {
  width: 10px;
  height: 10px;
  background: orange;
  border-radius: 50%;
  position: fixed;
  top: v-bind(pos.y);
  left: v-bind(pos.x);
}
</style>

Nous en avons un div élément qui reçoit des styles qui le feront ressembler à un cercle. Il utilise position: fixed il peut donc être placé n’importe où sur l’écran. La top et left les valeurs sont mises à jour chaque fois que pos changements de réf. v-bind dans les styles est l’une des fonctionnalités introduites dans Vue 3 qui permet de synchroniser les valeurs de style avec l’état réactif de Vue.

Mettons à jour le App.vue et inclure notre nouveau composant.

src/App.vue

<script setup>
import { ref } from "vue";
import HelloWorld from "./components/HelloWorld.vue";
import FadeSlideTransition from "./components/FadeSlideTransition.vue";
import StateDrivenAnimation from "./components/StateDrivenAnimation.vue";
import AnimatingList from "./components/AnimatingList.vue";

const show = ref(true);
</script>

<template>
  <StateDrivenAnimation />
  <AnimatingList />
  <button @click="show = !show">Toggle animation</button>
  <FadeSlideTransition>
    <div v-show="show">
      <img width="200" height="200" alt="Vue logo" src="https://www.telerik.com/blogs/./assets/logo.png" />
      <HelloWorld msg="Hello Vue 3 + Vite" />
    </div>
  </FadeSlideTransition>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Le GIF ci-dessous montre comment le cercle suit le curseur de la souris.

Cercle animé utilisant l'état réactif de Vue

Emballer

Il existe plusieurs façons d’ajouter des animations dans Vue.js, à commencer par le Transition et TransitionGroup composants et se terminant par des animations CSS natives ou JavaScript pures. Si vous souhaitez créer des animations plus complexes, vous pouvez envisager d’utiliser une bibliothèque avec des commandes d’animation intégrées, telles que Interface utilisateur de Kendo pour Vue. Il s’agit d’un kit d’interface utilisateur riche en fonctionnalités qui, outre le package d’animations, fournit également plus de 90 composants prêts à l’emploi pour la création d’applications modernes.




Source link

septembre 23, 2022