فهرست سرفصل‌های Vue
خانه (HOME) معرفی (Intro) دایرکتیوها (Directives) v-bind (v-bind) v-if (v-if) v-show (v-show) v-for (v-for) رویدادها (Events) v-on (v-on) متدها (Methods) تغییردهنده های رویداد (Event Modifiers) فرم ها (Forms) v-model (v-model) بایندینگ CSS (CSS Binding) ویژگی های محاسبه شده (Computed Properties) واچرها (Watchers) قالب ها (Templates) چرا، چگونه و راه اندازی (Why, How and Setup) اولین صفحه SFC (First SFC Page) کامپوننت ها (Components) پراپس (Props) کامپوننت های v-for (v-for Components) $emit() ($emit()) ویژگی های عبوری (Fallthrough) (Fallthrough Attributes) استایل Scoped (Scoped Styling) کامپوننت های محلی (Local Components) اسلات ها (Slots) v-slot (v-slot) اسلات های Scoped (Scoped Slots) کامپوننت های پویا (Dynamic Components) Teleport (Teleport) درخواست HTTP (HTTP Request) رفرنس های تمپلیت (Template Refs) هوک های چرخه عمر (Lifecycle Hooks) Provide/Inject (Provide/Inject) مسیریابی (Routing) ورودی های فرم (Form Inputs) انیمیشن ها (Animations) انیمیشن با v-for (Animations with v-for) بیلد (Build) Composition API (Composition API) ویژگی های توکار (Built-in Attributes) ویژگی 'is' ('is' Attribute) ویژگی 'key' ('key' Attribute) ویژگی 'ref' ('ref' Attribute) کامپوننت های توکار (Built-in Components) <KeepAlive> (<KeepAlive>) <Teleport> (<Teleport>) <Transition> (<Transition>) <TransitionGroup> (<TransitionGroup>) المان های توکار (Built-in Elements) <component> (<component>) <slot> (<slot>) <template> (<template>) نمونه کامپوننت (Component Instance) $attrs ($attrs) $data ($data) $el ($el) $parent ($parent) $props ($props) $refs ($refs) $root ($root) $slots ($slots) $emit() ($emit()) $forceUpdate() ($forceUpdate()) $nextTick() ($nextTick()) $watch() ($watch()) دایرکتیوها (Directives) v-bind (v-bind) v-cloak (v-cloak) v-for (v-for) v-html (v-html) v-if (v-if) v-else-if (v-else-if) v-else (v-else) v-memo (v-memo) v-model (v-model) v-on (v-on) v-once (v-once) v-pre (v-pre) v-show (v-show) v-slot (v-slot) v-text (v-text) گزینه های نمونه (Instance Options) داده ها (data) متدها (methods) محاسبه شده ها (computed) watch (watch) پراپس (props) emits (emits) expose (expose) هوک های چرخه عمر (Lifecycle Hooks) beforeCreate (beforeCreate) created (created) beforeMount (beforeMount) mounted (mounted) beforeUpdate (beforeUpdate) updated (updated) beforeUnmount (beforeUnmount) unmounted (unmounted) errorCaptured (errorCaptured) renderTracked (renderTracked) renderTriggered (renderTriggered) activated (activated) deactivated (deactivated) serverPrefetch (serverPrefetch) مثال ها (Examples) تمرین ها (Exercises) کوییز (Quiz) سیلابس (Syllabus) برنامه مطالعه (Study Plan) سرور (Server) گواهینامه (Certificate)
نتیجه‌ای برای جستجو یافت نشد.
Vue

Vue — انیمیشن ها (Animations)

آخرین بروزرسانی: 1404/08/21

انیمیشن ها (Animations)

تو Vue، «انیمیشن (Animation)» یعنی حرکت یا تغییر نرم. «ترنزیشن (Transition)» یعنی تغییر مرحله ای بین دو حالت. با CSS ساده هم می شود، اما کامپوننت <Transition> اضافه و حذف را راحت تر می کند.

مرور سریع CSS Transition و Animation

می توانیم با v-bind کلاس بدهیم و فقط با CSS حرکت بسازیم. شبیه وقتی دکمه ای را می زنی و با نرم بودن رنگ عوض می شود.

نمونه: چرخش با Transition

<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>

مشاهده در ادیتور

نمونه: جابه جایی با Animation

<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>

مشاهده در ادیتور

کامپوننت <Transition> برای افزودن و حذف

وقتی عنصر با v-if یا v-show ظاهر یا غیب می شود، <Transition> کار را ساده می کند. مثل نشان دادن پیام و محوشدنش.

نمونه: محوشدن هنگام حذف

<template>
  <h1>Add/Remove &lt;p&gt; 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>

مشاهده در ادیتور

شش کلاس آماده Transition

سه کلاس برای ورود است: v-enter-from، v-enter-active، v-enter-to. سه کلاس برای خروج است: v-leave-from، v-leave-active، v-leave-to. با این ها می توانی هم ورود هم خروج را بسازی.

نمونه: ورود و خروج با حرکت

<template>
  <h1>Add/Remove &lt;p&gt; 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>

مشاهده در ادیتور

کلاس های active و انیمیشن سفارشی

کلاس های v-enter-active و v-leave-active هنگام فرایند ورود یا خروج فعال اند. می توانی keyframes بدهی تا ورود و خروج خاص تر شود.

نمونه: keyframes برای ورود و خروج

<template>
  <h1>Add/Remove &lt;p&gt; 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>

مشاهده در ادیتور

prop نام برای چند Transition

با prop name می توانی کلاس ها را از v- به پیشوند دلخواه تغییر دهی. مثلا swirl-enter-active. این برای چند انیمیشن متفاوت مفید است.

نمونه: دو انیمیشن با نام های مختلف

<template>
  <h1>Add/Remove &lt;p&gt; Tag</h1>
  <p>Transition دوم name="swirl" دارد تا کلاس ها جدا شوند.</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>

مشاهده در ادیتور

هوک های جاوااسکریپتی Transition

هر کلاس رویدادی دارد؛ مثلا بعد از ورود، رویداد after-enter اجرا می شود. می توانی در آن کد بزنی؛ مثل روشن کردن یک باکس.

نمونه: استفاده از after-enter

<template>
  <h1>JavaScript Transition Hooks</h1>
  <p>پس از اتمام ورود، یک 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 enter-active.</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>

مشاهده در ادیتور

prop appear برای انیمیشنِ بار اول

اگر می خواهی هنگام لود صفحه انیمیشن اجرا شود، prop appear را به Transition بده.

نمونه: اجرای انیمیشن در لود اولیه

<template>
  <h1>The 'appear' Prop</h1>
  <p>با appear، انیمیشن در رندر اولیه اجرا می شود.</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>

مشاهده در ادیتور

جابجایی بین چند عنصر

می توانی بین چند تصویر سوییچ کنی. شرطش این است که همزمان فقط یکی نمایش شود. از v-if و v-else-if استفاده کن.

نمونه: سوییچ بین تصاویر

<template>
  <h1>Transition Between Elements</h1>
  <p>با کلیک، تصویر جدید می آید.</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;
  }
<\/style>

مشاهده در ادیتور

mode="out-in"؛ اول خروج، بعد ورود

اگر می خواهی عنصر جدید بعد از خروج قبلی بیاید، از mode="out-in" استفاده کن. این باعث نظم و بدون همپوشانی می شود.

نمونه: out-in برای تصاویر

<template>
  <h1>mode="out-in"</h1>
  <p>با out-in، ورود پس از خروج انجام می شود.</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;
  }
<\/style>

مشاهده در ادیتور

Transition برای کامپوننت های پویا

وقتی بین چند کامپوننت سوییچ می کنی، <component :is> را داخل <Transition> بگذار. سپس ورود و خروجشان انیمیشن می گیرد.

نمونه: سوییچ بین دو کامپوننت

<template>
  <h1>Transition with Dynamic Components</h1>
  <p>Transition دور کامپوننت پویا قرار می گیرد.</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;
    }
  }
<\/style>

مشاهده در ادیتور

نکته: در هر <Transition> فقط یک ریشه قابل انیمیشن مجاز است.

جمع بندی سریع

  • برای ورود و خروج، <Transition> بهترین گزینه است.
  • از شش کلاس v-* برای فازها استفاده کن.
  • با name چند انیمیشن جدا بساز.
  • برای لود اولیه از appear کمک بگیر.
  • نیاز به نظم داری؟ mode="out-in" بگذار.

بیشتر بخوان: انیمیشن های Vue، کامپوننت ها، و ورودی های فرم.