Vue animatsiyalar

Vue-dagi o‘rnatilgan <Transition> komponenti bizga v-if , v-show yoki dinamik komponentlar bilan qo‘shilgan yoki o‘chirilgan elementlarni animatsiya qilishda yordam beradi.

Boshqa hollarda oddiy CSS o‘tishlari va animatsiyalaridan foydalanishda hech qanday yomon narsa yo‘q.

ULASHISH

CSS o‘tish va animatsiyaga qisqacha kirish

Qo‘llanmaning ushbu qismi asosiy CSS animatsiyalari va o‘tishlari haqida bilimlarni talab qiladi.

Ammo animatsiyalarni yaratish uchun Vue o‘ziga xos o‘rnatilgan <Transition> komponentidan foydalanishdan oldin, keling, Vue bilan oddiy CSS animatsiyalari va o‘tishlaridan qanday foydalanish mumkinligi haqidagi ikkita misolni ko‘rib chiqaylik.

Misol

App.vue:

<template>
  <h1>Basic CSS Transition</h1>
  <button @click="this.doesRotate = true">Rotate</button>
  <div :class="{ rotate: doesRotate }"></div>
</template>

<script>
export default {
  data() {
    return {
      doesRotate: false
    }
  }
}
</script>

<style scoped>
  .rotate {
    rotate: 160deg;
    transition: rotate 1s;
  }
  div {
    border: solid black 2px;
    background-color: lightcoral;
    width: 60px;
    height: 60px;
  }
  h1, button, div {
    margin: 10px;
  }
</style>
Misolni ishga tushirish »

Yuqoridagi misolda biz v-bind dan <div> tegiga u aylanishi uchun class berish uchun foydalanamiz. Aylanish 1 soniya davom etishining sababi shundaki, u CSS transition xususiyati bilan aniqlanadi.

Quyidagi misolda biz CSS animatsiya xususiyatiga ega obyektni qanday ko‘chirishimiz mumkinligini ko‘rib chiqamiz.

Misol

App.vue:

<template>
  <h1>Basic CSS Animation</h1>
  <button @click="this.doesMove = true">Start</button>
  <div :class="{ move: doesMove }"></div>
</template>

<script>
export default {
  data() {
    return {
      doesMove: false
    }
  }
}
</script>

<style scoped>
  .move {
    animation: move .5s alternate 4 ease-in-out;
  }
  @keyframes move {
    from {
      translate: 0 0;
    }
    to {
      translate: 70px 0;
    }
  }
  div {
    border: solid black 2px;
    background-color: lightcoral;
    border-radius: 50%;
    width: 60px;
    height: 60px;
  }
  h1, button, div {
    margin: 10px;
  }
</style>
Misolni ishga tushirish »


komponenti

Yuqoridagi ikkita misolda bo‘lgani kabi oddiy CSS o‘tishlari va animatsiyalaridan foydalanishda hech qanday yomon narsa yo‘q.

Yaxshiyamki, Vue bizga v-if yoki v-show ilovamizdan olib tashlangan yoki unga qo‘shilgan elementni jonlantirmoqchi bo‘lgan hollarda bizga o‘rnatilgan <Transition> komponentini taqdim etadi, chunki buni oddiy CSS animatsiyasi bilan qilish qiyin.

Avval tugma <p> tegini qo‘shadigan yoki o‘chiradigan dastur yarataylik:

Misol

App.vue:

<template>
  <h1>Add/Remove <p> Tag</h1>
  <button @click="this.exists = !this.exists">{{btnText}}</button><br>
  <p v-if="exists">Hello World!</p>
</template>

<script>
export default {
  data() {
    return {
      exists: false
    }
  },
  computed: {
    btnText() {
      if(this.exists) {
        return 'Remove';
      }
      else {
        return 'Add';
      }
    }
  }
}
</script>

<style>
  p {
    background-color: lightgreen;
    display: inline-block;
    padding: 10px;
  }
</style>
Misolni ishga tushirish »

Endi <Transition> komponentini <p> tegi atrofiga o‘rab, <p> tegini olib tashlashni qanday jonlantirishimiz mumkinligini ko‘rib chiqamiz.

<Transition> komponentidan foydalanganda biz avtomatik ravishda elementlar qo‘shilgan yoki o‘chirilganda jonlantirish uchun foydalanishimiz mumkin bo‘lgan olti xil CSS classini olamiz.

Quyidagi misolda <p> yorlig‘i olib tashlanganida o‘chadigan animatsiya qilish uchun avtomatik ravishda mavjud bo‘lgan v-leave-from va v-leave-to sinflaridan foydalanamiz:

Misol

App.vue:

<template>
  <h1>Add/Remove <p> Tag</h1>
  <button @click="this.exists = !this.exists">{{btnText}}</button><br>
  <Transition>
    <p v-if="exists">Hello World!</p>
  </Transition>
</template>

<script>
export default {
  data() {
    return {
      exists: false
    }
  },
  computed: {
    btnText() {
      if(this.exists) {
        return 'Remove';
      }
      else {
        return 'Add';
      }
    }
  }
}
</script>

<style>
  .v-leave-from {
    opacity: 1;
  }
  .v-leave-to {
    opacity: 0;
  }
  p {
    background-color: lightgreen;
    display: inline-block;
    padding: 10px;
    transition: opacity 0.5s;
  }
</style>
Misolni ishga tushirish »

Oltita sinfi

<Transition> komponentidan foydalanganimizda avtomatik ravishda oltita class mavjud.

<Transition> komponenti ichidagi element sifatida qo‘shilgan, biz ushbu o‘tishni jonlantirish uchun ushbu dastlabki uchta classdan foydalanishimiz mumkin:

  1. v-enter-from
  2. v-enter-active
  3. v-enter-to

<Transition> komponenti ichida element o‘chirilgan sifatida biz keyingi uchta classdan foydalanishimiz mumkin:

  1. v-leave-from
  2. v-leave-active
  3. v-leave-to

Eslatma: <Transition> komponentining root darajasida faqat bitta element bo‘lishi mumkin.

Keling, <p> teg qo‘shilganda ham, o‘chirilganda ham jonlantirishimiz uchun ushbu sinflarning to‘rttasidan foydalanamiz.

Misol

App.vue:

<template>
  <h1>Add/Remove <p> Tag</h1>
  <button @click="this.exists = !this.exists">{{btnText}}</button><br>
  <Transition>
    <p v-if="exists">Hello World!</p>
  </Transition>
</template>

<script>
export default {
  data() {
    return {
      exists: false
    }
  },
  computed: {
    btnText() {
      if(this.exists) {
        return 'Remove';
      }
      else {
        return 'Add';
      }
    }
  }
}
</script>

<style>
  .v-enter-from {
    opacity: 0;
    translate: -100px 0;
  }
  .v-enter-to {
    opacity: 1;
    translate: 0 0;
  }
  .v-leave-from {
    opacity: 1;
    translate: 0 0;
  }
  .v-leave-to {
    opacity: 0;
    translate: 100px 0;
  }
  p {
    background-color: lightgreen;
    display: inline-block;
    padding: 10px;
    transition: all 0.5s;
  }
</style>
Misolni ishga tushirish »

Shuningdek, elementni qo‘shish yoki olib tashlash paytida uslub yoki animatsiyani o‘rnatish uchun v-enter-active va v-leave-active-dan foydalanishimiz mumkin:

Misol

App.vue:

<template>
  <h1>Add/Remove <p> Tag</h1>
  <button @click="this.exists = !this.exists">{{btnText}}</button><br>
  <Transition>
    <p v-if="exists">Hello World!</p>
  </Transition>
</template>

<script>
export default {
  data() {
    return {
      exists: false
    }
  },
  computed: {
    btnText() {
      if(this.exists) {
        return 'Remove';
      }
      else {
        return 'Add';
      }
    }
  }
}
</script>

<style>
  .v-enter-active {
    background-color: lightgreen;
    animation: added 1s;
  }
  .v-leave-active {
    background-color: lightcoral;
    animation: added 1s reverse;
  }
  @keyframes added {
    from {
      opacity: 0;
      translate: -100px 0;
    }
    to {
      opacity: 1;
      translate: 0 0;
    }
  }
  p {
    display: inline-block;
    padding: 10px;
    border: dashed black 1px;
  }
</style>
Misolni ishga tushirish »

O‘tish "nomi" Prop

Agar sizda bir nechta <Transition> komponentlar mavjud bo‘lsa-yu, lekin <Transition> komponentlaridan kamida bittasi boshqa animatsiyaga ega bo‘lishini istasangiz, ularni bir-biridan ajratish uchun <Transition> komponentlari uchun turli nomlar kerak bo‘ladi.

Biz <Transition> komponentining nomini name prop bilan tanlashimiz mumkin va u o‘tish classlari nomini ham o‘zgartiradi, shuning uchun biz ushbu komponent uchun turli CSS animatsiya qoidalarini o‘rnatishimiz mumkin.

<Transition name="swirl">

Agar o‘tish nomining tayanch qiymati "aylanma" ga o‘rnatilgan bo‘lsa, avtomatik ravishda mavjud classlar endi "v-" o‘rniga "swirl-" bilan boshlanadi:

  1. aylanib-kirish-dan
  2. aylanish-kirish-faol
  3. aylanish-kirish
  4. aylanmoq-dan
  5. aylanma-yaroqli-faol
  6. aylanmoq-natija

Quyidagi misolda biz <Transition> komponentlariga turli animatsiyalarni berish uchun name tayanchidan foydalanamiz. Bitta <Transition> komponentiga nom berilmagan va shuning uchun 'v-' bilan boshlanadigan avtomatik ravishda yaratilgan CSS classlari yordamida animatsiyalar beriladi. Boshqa <Transition> komponentiga 'swirl' nomi berilgan, shuning uchun unga 'swirl-' bilan boshlanadigan avtomatik ravishda yaratilgan CSS classlari bilan animatsiya qoidalari berilishi mumkin.

Misol

App.vue:

<template>
  <h1>Add/Remove <p> Tag</h1>
  <p>The second transition in this example has the name prop "swirl", so that we can keep the transitions apart with different class names.</p>
  <hr>
  <button @click="this.p1Exists = !this.p1Exists">{{btn1Text}}</button><br>
  <Transition>
    <p v-if="p1Exists" id="p1">Hello World!</p>
  </Transition>
  <hr>
  <button @click="this.p2Exists = !this.p2Exists">{{btn2Text}}</button><br>
  <Transition name="swirl">
    <p v-if="p2Exists" id="p2">Hello World!</p>
  </Transition>
</template>

<script>
export default {
  data() {
    return {
      p1Exists: false,
      p2Exists: false
    }
  },
  computed: {
    btn1Text() {
      if(this.p1Exists) {
        return 'Remove';
      }
      else {
        return 'Add';
      }
    },
    btn2Text() {
      if(this.p2Exists) {
        return 'Remove';
      }
      else {
        return 'Add';
      }
    }
  }
}
</script>

<style>
  .v-enter-active {
    background-color: lightgreen;
    animation: added 1s;
  }
  .v-leave-active {
    background-color: lightcoral;
    animation: added 1s reverse;
  }
  @keyframes added {
    from {
      opacity: 0;
      translate: -100px 0;
    }
    to {
      opacity: 1;
      translate: 0 0;
    }
  }
  .swirl-enter-active {
    animation: swirlAdded 1s;
  }
  .swirl-leave-active {
    animation: swirlAdded 1s reverse;
  }
  @keyframes swirlAdded {
    from {
      opacity: 0;
      rotate: 0;
      scale: 0.1;
    }
    to {
      opacity: 1;
      rotate: 360deg;
      scale: 1;
    }
  }
  #p1, #p2 {
    display: inline-block;
    padding: 10px;
    border: dashed black 1px;
  }
  #p2 {
    background-color: lightcoral;
  }
</style>

Misolni ishga tushirish »

JavaScript o‘tish hook’lari

Yuqorida aytib o‘tilganidek, har bir Transition klassi biz ba’zi JavaScript kodlarini ishga tushirishimiz mumkin bo‘lgan voqeaga mos keladi.

O‘tish classi JavaScript hodisasi
v-enter-from before-enter
v-enter-active kiriting
v-enter-to after-enter
enter-cancelled
v-leave-from before-leave
v-leave-active tark eting
v-leave-to after-leave
leave-cancelled (v-show only)

Quyidagi misolda after-enter hodisasi sodir bo‘lganda, qizil <div> elementni ko‘rsatadigan metod ishlaydi.

Misol

App.vue:

<template>
  <h1>JavaScript Transition Hooks</h1>
  <p>This code hooks into "after-enter" so that after the initial animation is done, a method runs that displays a red div.</p>
  <button @click="pVisible=true">Create p-tag!</button><br>
  <Transition @after-enter="onAfterEnter">
    <p v-show="pVisible" id="p1">Hello World!</p>
  </Transition>
  <br>
  <div v-show="divVisible">This appears after the "enter-active" phase of the transition.</div>
</template>

<script>
export default {
  data() {
    return {
      pVisible: false,
      divVisible: false
    }
  },
  methods: {
    onAfterEnter() {
      this.divVisible = true;
    }
  }
}
</script>

<style scoped>
  .v-enter-active {
    animation: swirlAdded 1s;
  }
  @keyframes swirlAdded {
    from {
      opacity: 0;
      rotate: 0;
      scale: 0.1;
    }
    to {
      opacity: 1;
      rotate: 360deg;
      scale: 1;
    }
  }
  #p1, div {
    display: inline-block;
    padding: 10px;
    border: dashed black 1px;
  }
  #p1 {
    background-color: lightgreen;
  }
  div {
    background-color: lightcoral;
  }
</style>
Misolni ishga tushirish »

enter-cancelled hodisasi ishga tushishi uchun <p> elementining kirish bosqichini to‘xtatish uchun quyidagi misoldagi “O‘chirish” tugmasidan foydalanishingiz mumkin:

Misol

App.vue:

<template>
  <h1>The 'enter-cancelled' Event</h1>
  <p>Click the toggle button again before the enter animation is finished to trigger the 'enter-cancelled' event.</p>
  <button @click="pVisible=!pVisible">Toggle</button><br>
  <Transition @enter-cancelled="onEnterCancelled">
    <p v-if="pVisible" id="p1">Hello World!</p>
  </Transition>
  <br>
  <div v-if="divVisible">You interrupted the "enter-active" transition.</div>
</template>

<script>
export default {
  data() {
    return {
      pVisible: false,
      divVisible: false
    }
  },
  methods: {
    onEnterCancelled() {
      this.divVisible = true;
    }
  }
}
</script>

<style scoped>
  .v-enter-active {
    animation: swirlAdded 2s;
  }
  @keyframes swirlAdded {
    from {
      opacity: 0;
      rotate: 0;
      scale: 0.1;
    }
    to {
      opacity: 1;
      rotate: 720deg;
      scale: 1;
    }
  }
  #p1, div {
    display: inline-block;
    padding: 10px;
    border: dashed black 1px;
  }
  #p1 {
    background-color: lightgreen;
  }
  div {
    background-color: lightcoral;
  }
</style>
Misolni ishga tushirish »

"Ko‘rinish" Prop

Agar sahifa yuklanganda jonlantirmoqchi bo‘lgan elementimiz bo‘lsa, biz <Transition> komponentida appear propidan foydalanishimiz kerak.

<Transition appear>
  ...
</Transition>

Ushbu misolda, sahifa birinchi marta yuklanganda paydo bo‘lgan prop animatsiyani boshlaydi:

Misol

App.vue:

<template>
  <h1>The 'appear' Prop</h1>
  <p>The 'appear' prop starts the animation when the p tag below is rendered for the first time as the page opens. Without the 'appear' prop, this example would have had no animation.</p>
  <Transition appear>
    <p id="p1">Hello World!</p>
  </Transition>
</template>

<style>
  .v-enter-active {
    animation: swirlAdded 1s;
  }
  @keyframes swirlAdded {
    from {
      opacity: 0;
      rotate: 0;
      scale: 0.1;
    }
    to {
      opacity: 1;
      rotate: 360deg;
      scale: 1;
    }
  }
  #p1 {
    display: inline-block;
    padding: 10px;
    border: dashed black 1px;
    background-color: lightgreen;
  }
</style>

Misolni ishga tushirish »

Elementlar orasidagi o‘tish

<Transition> komponentidan bir nechta elementlar o‘rtasida almashish uchun ham foydalanish mumkin, agar biz <v-if> va <v-else-if> yordamida bir vaqtning o‘zida faqat bitta element ko‘rsatilishiga ishonch hosil qilsak:

Misol

App.vue:

<template>
  <h1>Transition Between Elements</h1>
  <p>Click the button to get a new image.</p>
  <p>The new image is added before the previous is removed. We will fix this in the next example with mode="out-in".</p>
  <button @click="newImg">Next image</button><br>
  <Transition>
    <img src="/img_pizza.svg" v-if="imgActive === 'pizza'">
    <img src="/img_apple.svg" v-else-if="imgActive === 'apple'">
    <img src="/img_cake.svg" v-else-if="imgActive === 'cake'">
    <img src="/img_fish.svg" v-else-if="imgActive === 'fish'">
    <img src="/img_rice.svg" v-else-if="imgActive === 'rice'">
  </Transition>
</template>

<script>
export default {
  data() {
    return {
      imgActive: 'pizza',
      imgs: ['pizza', 'apple', 'cake', 'fish', 'rice'],
      indexNbr: 0
    }
  },
  methods: {
    newImg() {
      this.indexNbr++;
      if(this.indexNbr >= this.imgs.length) {
        this.indexNbr = 0;
      }
      this.imgActive = this.imgs[this.indexNbr];
    }
  }
}
</script>

<style>
  .v-enter-active {
    animation: swirlAdded 1s;
  }
  .v-leave-active {
    animation: swirlAdded 1s reverse;
  }
  @keyframes swirlAdded {
    from {
      opacity: 0;
      rotate: 0;
      scale: 0.1;
    }
    to {
      opacity: 1;
      rotate: 360deg;
      scale: 1;
    }
  }
  img {
    width: 100px;
    margin: 20px;
  }
  img:hover {
    cursor: pointer;
  }
</style>
Misolni ishga tushirish »

mode="out-in"

Yuqoridagi misolda oldingi rasm o‘chirilishidan oldin keyingi rasm qo‘shiladi.

Biz <Transition> komponentida mode="out-in" tayanch va tayanch qiymatidan foydalanamiz, shunda keyingi element qo‘shilishidan oldin elementni olib tashlash tugallanadi.

Misol

Bu misolda mode="out-in" ga qo‘shimcha ravishda biz oldingi misolda ishlatgan "newImg" usuli o‘rniga "imgActive" hisoblangan qiymati ham qo‘llaniladi.

App.vue:

<template>
  <h1>mode="out-in"</h1>
  <p>Click the button to get a new image.</p>
  <p>With mode="out-in", the next image is not added until the current image is removed. Another difference from the previous example, is that here we use computed prop instead of a method.</p>
  <button @click="indexNbr++">Next image</button><br>
  <Transition mode="out-in">
    <img src="/img_pizza.svg" v-if="imgActive === 'pizza'">
    <img src="/img_apple.svg" v-else-if="imgActive === 'apple'">
    <img src="/img_cake.svg" v-else-if="imgActive === 'cake'">
    <img src="/img_fish.svg" v-else-if="imgActive === 'fish'">
    <img src="/img_rice.svg" v-else-if="imgActive === 'rice'">
  </Transition>
</template>

<script>
export default {
  data() {
    return {
      imgs: ['pizza', 'apple', 'cake', 'fish', 'rice'],
      indexNbr: 0
    }
  },
  computed: {
    imgActive() {
      if(this.indexNbr >= this.imgs.length) {
        this.indexNbr = 0;
      }
      return this.imgs[this.indexNbr];
    }
  }
}
</script>

<style>
  .v-enter-active {
    animation: swirlAdded 0.7s;
  }
  .v-leave-active {
    animation: swirlAdded 0.7s reverse;
  }
  @keyframes swirlAdded {
    from {
      opacity: 0;
      rotate: 0;
      scale: 0.1;
    }
    to {
      opacity: 1;
      rotate: 360deg;
      scale: 1;
    }
  }
  img {
    width: 100px;
    margin: 20px;
  }
  img:hover {
    cursor: pointer;
  }
</style>
Misolni ishga tushirish »

Dinamik komponentlar bilan o‘tish

Dinamik komponentlar o‘rtasida almashinishni jonlantirish uchun <Transition> komponentidan ham foydalanishimiz mumkin:

Misol

App.vue:

<template>
  <h1>Transition with Dynamic Components</h1>
  <p>The Transition component wraps around the dynamic component so that the switching can be animated.</p>
  <button @click="toggleValue = !toggleValue">Switch component</button>
  <Transition mode="out-in">
    <component :is="activeComp"></component>
  </Transition>
</template>

<script>
  export default {
    data () {
      return {
        toggleValue: true
      }
    },
    computed: {
      activeComp() {
        if(this.toggleValue) {
          return 'comp-one'
        }
        else {
          return 'comp-two'
        }
      }
    }
  }
</script>

<style>
  .v-enter-active {
    animation: slideIn 0.5s;
  }
  @keyframes slideIn {
    from {
      translate: -200px 0;
      opacity: 0;
    }
    to {
      translate: 0 0;
      opacity: 1;
    }
  }
  .v-leave-active {
    animation: slideOut 0.5s;
  }
  @keyframes slideOut {
    from {
      translate: 0 0;
      opacity: 1;
    }
    to {
      translate: 200px 0;
      opacity: 0;
    }
  }
  #app {
    width: 350px;
    margin: 10px;
  }
  #app > div {
    border: solid black 2px;
    padding: 10px;
    margin-top: 10px;
  }
</style>
Misolni ishga tushirish »

Vue mashqlari

O‘zingizni mashqlar bilan sinab ko‘ring

Mashq:

komponenti avtomatik ravishda elementni jonlantirish uchun foydalanishimiz mumkin bo‘lgan 6 xil CSS classini beradi.

Element paydo bo‘layotganda dastlabki 3 ta class nomi to‘g‘ri bo‘lishi uchun bo‘sh joylarni to‘ldiring:

  1. v-enter-
  2. v-enter-
  3. v-enter-

Mashqni boshlash



W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!