vue 之 Transition && 各种动画实现,一文让你会动画

在开发中,如果没有动画的话,整个页面内容的显示和隐藏会非常的生硬!不好看,为了给予一定的用户体验,进入今天的主题

React框架本身并没有提供任何动画相关的API,所以如果需要使用的话可以使用一个第三方库react-transition-group
Vue中为我们提供了一些内置的组件和对应的API来完成动画 
一、Transition组件
1.Transition组件的原理
当插入或删除包含在transition组件中的元素时,vue将会做以下处理

就是 : 会自动把类加入到 transition组件下的根元素中,transition里面只能放单个标签( 组件 )

添加或者删除的class,常用的是如下六个 

进入 :


离开 : 

 

 


2. Используйте
код перехода в компоненте перехода
<template>
  <div class="box">
    <button @click="isShow = !isShow">switch</button>
    <!-- Оберните его переходом и назовите его run . Префикс имени класса run-->
    <transition name="run">
      <!-- Отображение и скрытие внутренних элементов или компонентов вызовет эффект перехода-->
      <div v-if="isShow" >
        <span> 123123123123</span>
      </div>
    </transition>
  </div>
</template>
 
<script>
export default {   data() {     return {       isShow:true     };   } } ; </script> <style lang="scss" scoped> // Состояние, в котором элемент начинает входить | Состояние, в котором элемент покидает end.run -enter-from,







 



.run-leave-to {
  opacity: 0;
}
// 元素进入结束的状态 | 元素开始离开的状态。     这里不写也可以!!!!!!
.run-enter-to,
.run-leave-from {
  opacity: 1;
}
// 元素进入 | 结束时,过渡的效果
.run-enter-active,
.run-leave-active {
  // 过渡动画的使用
  transition: opacity 2s linear 0s;
}
</style>
效果 


说明



3. Используйте код анимации в компоненте Transition
<style lang="scss" scoped>
/**
* Если это анимационный эффект, изменяется более одного состояния
* Просто установите динамический jike
* */
.run-enter-active {   animation: run -scale 1s linear 0s; } // установить обратное значение при выходе.run -leave-active { animation     :   run-scale 1s linear 0s reverse; } @keyframes run-scale {   0% { 0);   }   50% {     transform: scale(1.3);   }   100% {     transform: scale(1);   } } </style> Эффект



















4. Атрибут type компонента Transition
встречается: когда мы используем одновременно переход и анимацию

Код
<style lang="scss" scoped>
// Состояние, в котором элемент начинает входить | Состояние, в котором элемент покидает конец
.run-enter-from,
.run-leave-to {   opacity: 0; } // Состояние, когда элемент входит в конец| Состояние, когда элемент начинает выходить.run -enter-to, .run-leave-from {   opacity: 1; } // Когда элемент входит | -enter-active, .run-leave-active {   // Использование анимации   перехода transition: opacity 2s linear 0s; } .run-enter-active {   animation: run-scale 2s linear 0s; } // установка на противоположное при выходе   . _ _   _






















    преобразование: масштаб (0);
  }
  50% {     преобразование: масштаб (1.3);   }   100% {     преобразование: масштаб (1);   } } </style>效果








Совет: чтобы узнать о завершении перехода, Vue отслеживает переходы и анимации внутри.

Если используется только один из них, Vue может автоматически определить тип и установить прослушиватель.

Но проблемы могут возникнуть, если использовать одновременно:

Возможно, выполнение одной анимации закончилось, а другая анимация не закончилась (установка времени другая)
решение

Установите для атрибута type значение перехода и анимации, чтобы четко указать тип прослушивания Vue, время которого будет преобладать
<template>
  <div class="box">
    <button @click="isShow = !isShow">switch</button>
    < !-- здесь указывает, какое время использовать в качестве стандартного -->
    <transition name="run" type="transition || animation">
      <div v-if="isShow">
        <span>123123123123</span>
      < /div>
    </transition>
  </div>
</template>
Отступление: На самом деле, вообще-то выставлено одно и то же время, а зачем ставить переход, когда есть анимация? Это магический атрибут~


5. Базовая настройка атрибута продолжительности компонента Transition (используется редко) : установить время входа и выхода одновременно
<transition name="run" :duration="1000">
  <div v-if="isShow ">
    <span> 123123123123</span>
  </div>
</transition>
После использования таким образом время перехода и окончания анимации, установленное в css, будет недействительным, и время продолжительности будет иметь преимущественную силу.

Настройки объекта: установить время входа и выхода соответственно
<transition name="run" :duration="{ enter: 800, leave: 1000 }">
  <div v-if="isShow">
    <span>123123123123</span >
  </div>
</transition>
6. Атрибут режима компонента Transition
Если два элемента (компонента) обернуты в компонент перехода и отображают друг друга, произойдут ужасные вещи

代码
<template>
  <div class="box">
    <button @click="isShow = !isShow">切换</button>
    <transition name="run">
      <div v-if="isShow">
        <span> один</span>
      </div>
      <div v-else>
        <span>два</span>
      </div>
    </transition>
  </div>
</template>
 
<script>
export default {   data() {     return {       isShow: правда     };   } }; </script> <style lang="scss" с областью действия> .







 





.run-leave-active {   анимация: run-scale 2s linear 0s reverse; } @keyframes run-scale {   0% {     transform: scale(0);   }   50% {     преобразование: масштаб (1.3);   }   100% {     преобразование: масштаб (1);   } } </ стиль>













Эффект 


Причина и решение
Причина: по умолчанию анимация входа и выхода происходит одновременно.

Решение: установите атрибут режима

<transition name="run" mode="in-out || out-in">
  <div v-if="isShow">
    <span>один</span>
  </div>
  <div v-else>
    <span >два</span>
  </div>
</transition>
режим: вход-выход

режим: выход-вход

7. Атрибут появления компонента «Переход».
Если вы хотите, чтобы анимация отображалась сразу после обновления страницы, вам необходимо добавить

<transition name="run" mode="out-in" появляются>
  <div v-if="isShow">
    <span>один</span>
  </div>
  <div v-else>
    <span>два</ span>
  </div>
</transition>
8、 Transition组件的回调函数
<transition
  @before-enter="beforeEnter"
  @enter="enter"
  @after-enter="afterEnter"
  @enter-cancelled="enterCancelled"
  @ before-leave="beforeLeave"
  @leave="leave"
  @after-leave="afterLeave"
  @leave-cancelled="leaveCancelled"
  :css="false"
>
  <div v-if="isShow">
    <span>один</span>
  </div>
</transition>
:css="false". Vue пропустит обнаружение CSS, повысит производительность и предотвратит влияние стилей CSS в процессе перехода.

before-enter: запуск перед началом анимации ---- from, операция инициализации
enter: запуск при запуске анимации ---- active, запись js, выполнение определенной анимации
after-enter: запуск после запуска анимации ---- до, конец, завершение работы
ввод-отмена: срабатывает, когда анимация не может войти
перед выходом: срабатывает до того, как анимация покидает выход
: срабатывает, когда анимация завершается
после выхода: срабатывает после того, как анимация покидает
выход-отменяется: срабатывает, когда анимация не уходит


el : элемент, который выполняет анимацию

done : при использовании javaScript для выполнения анимации перехода требуется обратный вызов done, иначе они будут вызываться синхронно и переход будет завершен немедленно. 

  Затем используйте другие упакованные сторонние библиотеки анимации ~

2. Используйте стороннюю библиотеку анимации animate.css
Animate.css | Кроссбраузерная библиотека анимации CSS.

1. Установите
npm install animate.css
2. Импорт
Импортируйте в main.js

импортировать 'animate.css'
3. Использовать 01-использовать код
в css

<template>
  <div class="box">
    <button @click="isShow = !isShow">切换</button>
    <transition name="run" появления>
      <div v-if="isShow">
        <span> один</span>
      </div>
    </transition>
  </div>
</template>
 
<script>
export default {   data() {     return {       isShow: true     };   } }; </script> <style lang="scss" scoped> .run-enter-active {   анимация: lightSpeedInRight 2s linear 0s; } .   run-leave-active { анимация: lightSpeedOutRight 2s linear 0s; } </стиль>







 








Эффект 

иллюстрировать 

02- Используйте имя класса
здесь, вам нужно использовать enter-active-class и leave-active-class, часть css не может быть написана

код

Имя писать не нужно, если написать имя класса, то приоритет имени класса будет выше

<template>
  <div class="box">
    <button @click="isShow = !isShow">切换</button>
    <transition enter-active-class="animate__animated animate__backInDown" leave-active-class="animate__animated animate__backOutLeft" >
      <div v-if="isShow">
        <span>один</span>
      </div>
    </transition>
  </div>
</template>
效果 

иллюстрировать 

3. Использование библиотеки gsap (библиотеки JS)
 GreenSock - Документы - Gsap

В некоторых случаях, если вы хотите добиться анимационных эффектов с помощью JavaScript, вы можете использовать библиотеку gsap для завершения

GSAP: Аббревиатура GreenSock Animation Platform (GreenSock Animation Platform)
может анимировать свойства CSS, SVG, Canvas и т. д. с помощью JavaScript и совместима с браузерами.


1. Установите
npm install gsap   
2. Импорт
 можно импортировать внутри компонента

импортировать gsap из 'gsap'
3. Используйте
функции обратного вызова ввода и вывода

<шаблон>
  <div class="box">
    <button @click="isShow = !isShow">切换</button>
    <переход появляется @enter="enter" @leave="leave" :css="false">
      <div v-if="isShow">
        <span>one</span>
      </div>
    </transition>
  </div>
</template>
<script>
// 导入
import gsap from 'gsap'
export default {   data () {     return {       isShow: true     }   },   method: {     enter(el, done) {       // 从哪里来       gsap.from(el, {         // уменьшаем до 0         scale: 0,         // прозрачность












        opacity: 0,
        // 持续时间
        duration: 1,
        // translatex便宜200
        x: 200,
        // 这样设置比较好
        onComplete: done
      })
    },
    /**
     * 这里只需要制定最开始的状态,不用制定后面的状态,有点不好理解
     */
    leave(el, done) {
      // 到哪里去
      gsap.to(el, {
        scale: 0,
        opacity: 0,
        duration: 1,
        x: -200,
        onComplete: done
      })
    }
  }
}
</script>
<style lang="scss" scoped></style>
4.效果 


5.gsap额外补充 ( 数字变化效果 )
代码
<template>
  <div class="box">
    <input type="number" step="100" v-model="count" />
    <div>
      <span class="text-color">{ { showNumber.toFixed(0) }}</span>
    </div>
  </div>
</template>
<script>
import gsap from 'gsap'
export default {
  data() {
    return {
      count: 0,
      showNumber: 0
    }
  },
  watch: {
    // 监听输入值的改变
    count(newValue) {
      // 把当前this存进去,实时更改showNumber的值
      gsap.to(this, { duration: 0.5, showNumber: newValue })
    }
  }
}
</script>
<style lang="scss" scoped>
.box {   padding: 200px;   цвет фона: небесно-голубой;   box-shadow: 0 0 100px 0 небесно-голубой;   input {     граница: 3px сплошная rgb(7, 172, 237);     радиус границы: 10px;     отступ: 5px 10px;     ширина: 100 пикселей;     цвет фона: небесно-голубой;   }   .text-color {     display: inline-block;     фоновое изображение: линейный градиент (вправо, оранжевый, фиолетовый);     фоновый клип: текст;     цвет: прозрачный;     размер шрифта: 50px;   } } </style>效果




















4. Переходная группа перехода списка
В приведенной выше статье анимация перехода предназначена только для одного элемента или одного компонента.Если вы хотите отобразить список и добавить или удалить данные в списке, вам также нужна анимация исполнение

Используйте группу перехода: 

1.列表数字增加删除效果
01-代码 
<template>
  <div class="box">
    <div>
      <button @click="addNum">添加</button>
      <button @click="removeNum">删除</button>
    </div>
    <transition-group tag="p" name="run">
      <span class="item" v-for="item in dataList" :key="item">{ { item }}</span>
    </transition-group>
  </div>
</template>
<script>
export default {
  data() {
    return {
      dataList: [1, 2, 3, 4, 5, 6, 7, 8, 9],
      defaultNumber: 10
    }
  },
  methods: {
    // 随机位置增加一个数字
    addNum() {
      this.dataList.splice(this.randomIndex(), 0, this.defaultNumber++)
    },
    // удалить число в произвольной позиции
    removeNum() {       this.dataList.splice(this.randomIndex(), 1)     },     // random Занять позицию     randomIndex() {       return Math.floor(Math.random() * this.dataList.length)     }   } } </script> <style lang="scss" scoped> .item {   display: inline-block;   margin-right: 10px;   display: встроенный блок;   background-image: линейный градиент (вправо, оранжевый, фиолетовый);   background-clip: текст;   цвет: прозрачный;   размер шрифта: 30px ;



















.run-enter-from,
.run-leave-to {   непрозрачность: 0;   преобразование: перевести Y (50 пикселей); } .run-enter-active, .run-leave-active {   переход: все 1, линейные 0; } </style>效果 








02. Оптимизация эффектов 
Точки оптимизации: новые добавленные и удаленные узлы имеют анимацию, но нет анимации для других узлов, которые необходимо переместить.

Анимацию можно сделать через недавно добавленный класс v-move, который будет применяться в процессе изменения положения элемента.

css-код

<style lang="scss" с областью действия>
.item {   display: inline-block;   поле справа: 10px;   отображение: встроенный блок;   фоновое изображение: линейный градиент (вправо, оранжевый, фиолетовый);   фоновый клип: текст;   цвет: прозрачный;   размер шрифта: 30px; } .run-enter-from, .run-leave-to {   непрозрачность: 0;   преобразование: перевести Y (50 пикселей); } .run-enter-active, .run-leave-active {   переход: все 1, линейные 0; } // 移除的时候需要加上.run-leave-active {   position: absolute; } // 加上这个.run-move {   transition: transform 1s linear 0s;
























}
</style>
效果

03.增加洗牌效果
one-安装lodash库 

npm install lodash
two-导入

import _ from 'lodash'
three-使用

<template>
  <div class="box">
    <div>
      <button @click="addNum">Добавить</button>
      <button @click="removeNum">删除</button>
      <button @click="shuffleNum" >洗牌</button>
    </div>
    <transition-group tag="p" name="run">
      <span class="item" v-for="item in dataList" : key="item">{ { item }}</span>
    </transition-group>
  </div>
</template>
<script>
import _ from 'lodash'
export default {   data() {     return {       dataList: [ 1, 2, 3, 4, 5, 6, 7, 8, 9],       defaultNumber: 10     }   },   методы: {







    // Добавляем число в случайном месте
    addNum() {       this.dataList.splice(this.randomIndex(), 0, this.defaultNumber++)     },     // Удаляем число в случайном месте     removeNum() {       this.dataList. splice(this.randomIndex(), 1)     },     // Перемешать     shuffleNum() {       this.dataList = _.shuffle(this.dataList)     },     // Выбрать случайную позицию     randomIndex() {       return Math.floor(Math. random() * this.dataList.length)     }   } } </script> <style lang="scss" scoped> .item {   display: inline-block;   margin-right: 10px;   display: inline-block;






















  фоновое изображение: линейный градиент (вправо, оранжевый, фиолетовый);
  фоновый клип: текст;
  цвет: прозрачный;
  размер шрифта: 30 пикселей;
}
.run-enter-from,
.run-leave-to {   непрозрачность: 0 ;   transform: translateY(50px); } .run-enter-active, .run-leave-active {   transition: all 1s linear 0s; } // нужно добавить .run-leave-active {   position: absolute; } //   Добавьте это свойство . _ _  
















2. Альтернативный эффект анимации списка
01-реализован с помощью
кода css

<template>
  <div class="box">
    <input type="text" v-model="keyWords" />
    <transition-group tag="ul" name="run" class="nav">
      <li class ="item" v-for="item in filterData" :key="item">{ { item }}</li>
    </transition-group>
  </div>
</template>
 
<script>
export default {   data () {     return {       keyWords: '',       dataList: ['abc', 'bac', 'aec', 'qqw', 'qbf', 'aaa', 'afa'] } }     ,   вычислено   : {     // 赛选一下     filterData() {       return this.dataList.filter((item) => item.includes(this.keyWords))     }   }












}
</script>
 
<style lang="scss" scoped>
.run-enter-from,
.run-leave-to {   opacity: 0;   преобразование: перевести X (100 пикселей) повернуть (180 градусов); } .run-enter-active, .run-leave-active {   переход: все 1, линейные 0; } .box {   padding: 100px 0;   цвет фона: небесно-голубой;   box-shadow: 0 0 100px 0 небесно-голубой;   дисплей: гибкий;   flex-направление: столбец;   выравнивание содержимого: по центру;   выравнивание элементов: по центру;   input {     граница: 3px сплошная rgb(7, 172, 237);     радиус границы: 10px;     отступ: 5px 10px;     ширина: 100 пикселей;




















    цвет фона: небесно-голубой;
  }
  .text-color {     display: inline-block;     фоновое изображение: линейный градиент (вправо, оранжевый, фиолетовый);     фоновый клип: текст;     цвет: прозрачный;     размер шрифта: 50px;   } } .nav {   ширина: 100%;   дисплей: гибкий;   стиль списка: нет;   маржа: 0;   заполнение: 0;   выравнивание текста: по центру;   .item {     гибкий: 1;   } } </ стиль>


















Эффект 

ps: Потом пропадает и появляется одновременно, а эффекта чередования не добиться

02-Используйте js для реализации анимации.
Через атрибут задержки реализуйте эффект чередования.

код

<template>
  <div class="box">
    <input type="text" v-model="keyWords" />
    <transition-group tag="ul" name="run" class="nav" @enter=" введите" @leave="leave" появляйтесь>
      <!-- Используйте атрибуты, такие как data-*, чтобы добавить индекс к каждому элементу анимации -->
      <li class="item" v-for="(item, index) в filterData" :данные-индекс="индекс" :key="item">
        { { item }}
      </li>
    </transition-group>
  </div>
</template>
 
<script>
import gsap from 'gsap'
export default {   data() {     return {       keyWords: ' ',       dataList: ['abc', 'bac', 'aec', 'qqw', 'qbf', 'aaa', 'afa'], // Извлекаем параметры       анимации





      transitionOption: {         непрозрачность: 0,         масштаб: 0,5,         высота: 0,         поворот: 360       }     }   },   вычисленный: {     // выберите     filterData() {       return this.dataList.filter((item) => item.includes( this. keyWords))     }   },   method: {     enter(el, done) {       gsap.from(el, {         ...this.transitionOption, // Установить время задержки, так как оно переменное, поэтому каждая         задержка         должна быть разной         xPercent: -20,         onComplete: готово       })     },     оставить (el, сделано) {
























      gsap.to(el, {         ...this.transitionOption, // Устанавливаем время задержки, потому что оно переменное, поэтому у каждого должно быть разное         delay: el.dataset.index * 0.2,         xPercent: 20,         onComplete: done       } ) }     }   } </script> < style lang="scss" scoped> .box {   padding: 100px 0;   background-color: голубой;   box-shadow: 0 0 100px 0 skyblue;   display: flex;   flex-direction: column ;   выравнивание содержимого: по центру;   выравнивание элементов: по центру;   ввод {     граница: 3 пикселя сплошной rgb (7, 172, 237);     радиус границы: 10 пикселей;     отступы: 5 пикселей 10 пикселей;     ширина: 100 пикселей;









 














    цвет фона: небесно-голубой;
  }
  .text-color {     display: inline-block;     фоновое изображение: линейный градиент (вправо, оранжевый, фиолетовый);     фоновый клип: текст;     цвет: прозрачный;     размер шрифта: 50px;   } } .nav {   ширина: 100%;   // дисплей: гибкий;   стиль списка: нет;   маржа: 0;   заполнение: 0;   выравнивание текста: по центру;   положение: родственник;   .item {     гибкий: 1;   } } </style>效果 




















Supongo que te gusta

Origin blog.csdn.net/qq_40999917/article/details/129780587
Recomendado
Clasificación