فهرست سرفصل‌های 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 — انیمیشن با v-for (Animations with v-for)

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

انیمیشن با v-for (Animations with v-for)

می خواهی فهرست هایت قشنگ جان بگیرند؟ با «انیمیشن با v-for» و کامپوننت «TransitionGroup» هر آیتم، ورود و خروج نرمی دارد. «TransitionGroup» یک ظرف ویژه است که عناصر ساخته شده با v-for را جداگانه انیمیت می کند.

معرفی TransitionGroup

کامپوننت <TransitionGroup> دور عناصر v-for می نشیند و برای هر آیتم انیمیشن جدا می سازد. «کلید (key)» شناسه یکتا است؛ با آن Vue هر آیتم را درست دنبال می کند.

نمونه پایه با tag و key

<TransitionGroup tag="ol">
  <li v-for="x in products" :key="x">
    {{ x }}
  </li>
</TransitionGroup>

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

استایل های ورود با کلاس های v-*

<style>
  .v-enter-from {
    opacity: 0;
    rotate: 180deg;
  }
  .v-enter-to {
    opacity: 1;
    rotate: 0deg;
  }
  .v-enter-active {
    transition: all 0.7s;
  }
<\/style>

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

افزودن آیتم ها با انیمیشن

با افزودن هر نام تازه به آرایه، آیتم جدید با انیمیشن وارد می شود. مثل اضافه کردن دانش آموز جدید به صف، اما با ورود نرم.

App.vue: افزودن محصول جدید

<template>
  <h3>The &lt;TransitionGroup&gt; Component</h3>
  <p>New products are given animations using the &lt;TransitionGroup&gt; component.</p>
  <input type="text" v-model="inpName">
  <button @click="addEl">Add</button>
  <TransitionGroup tag="ol">
    <li v-for="x in products" :key="x">
      {{ x }}
    </li>
  </TransitionGroup>
</template>

<script>
export default {
  data() {
    return {
      products: ['Apple', 'Pizza', 'Rice'],
      inpName: ''
    };
  },
  methods: {
    addEl() {
      const el = this.inpName;
      this.products.push(el);
      this.inpName = null;
    }
  }
};
<\/script>

<style>
  .v-enter-from {
    opacity: 0;
    rotate: 180deg;
  }
  .v-enter-to {
    opacity: 1;
    rotate: 0deg;
  }
  .v-enter-active {
    transition: all 0.7s;
  }
<\/style>

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

حذف آیتم ها و جابجایی بقیه

اگر وسط فهرست حذف کنی، بقیه باید جای خالی را پر کنند. بدون تنظیم درست، ناگهانی می پرند. با کلاس «v-move»، حرکتشان نرم می شود.

App.vue: بدون v-move (پرش ناگهانی)

<template>
  <h3>The &lt;TransitionGroup&gt; Component</h3>
  <p>New products are given animations using the &lt;TransitionGroup&gt; component.</p>
  <button @click="addDie">Roll</button>
  <button @click="removeDie">Remove random</button><br>
  <TransitionGroup>
    <div v-for="x in dice" :key="x" class="diceDiv" :style="{ backgroundColor: 'hsl(' + x * 40 + ',85%,85%)' }">
      {{ x }}
    </div>
  </TransitionGroup>
</template>

<script>
export default {
  data() {
    return {
      dice: [],
      inpName: ''
    };
  },
  methods: {
    addDie() {
      const newDie = Math.ceil(Math.random() * 6);
      this.dice.push(newDie);
    },
    removeDie() {
      if (this.dice.length > 0) {
        this.dice.splice(Math.floor(Math.random() * this.dice.length), 1);
      }
    }
  },
  mounted() {
    this.addDie();
    this.addDie();
    this.addDie();
  }
};
<\/script>

<style>
  .v-enter-from {
    opacity: 0;
    translate: 200px 0;
    rotate: 360deg;
  }
  .v-enter-to {
    opacity: 1;
    translate: 0 0;
    rotate: 0deg;
  }
  .v-enter-active,
  .v-leave-active {
    transition: all 0.7s;
  }
  .v-leave-from {
    opacity: 1;
  }
  .v-leave-to {
    opacity: 0;
  }
  .diceDiv {
    margin: 10px;
    width: 30px;
    height: 30px;
    line-height: 30px;
    vertical-align: middle;
    text-align: center;
    border: solid black 1px;
    border-radius: 5px;
    display: inline-block;
  }
<\/style>

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

فعال کردن v-move و حل پرش

<style>
  .v-enter-from {
    opacity: 0;
    translate: 200px 0;
    rotate: 360deg;
  }
  .v-enter-to {
    opacity: 1;
    translate: 0 0;
    rotate: 0deg;
  }
  .v-enter-active,
  .v-leave-active,
  .v-move {
    transition: all 0.7s;
  }
  .v-leave-active {
    position: absolute;
  }
  .v-leave-from {
    opacity: 1;
  }
  .v-leave-to {
    opacity: 0;
  }
  .diceDiv {
    margin: 10px;
    width: 30px;
    height: 30px;
    line-height: 30px;
    vertical-align: middle;
    text-align: center;
    border: solid black 1px;
    border-radius: 5px;
    display: inline-block;
  }
<\/style>

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

مثال بزرگ تر: افزودن، حذف، مرتب سازی

با این نمونه، همه چیز واضح تر می شود. می توانی حذف با کلیک، مرتب سازی، و افزودن تصادفی داشته باشی. فهرست کامل نرم جابجا می شود.

App.vue: dice با کلید یکتا و جابجایی نرم

<template>
  <h3>The &lt;TransitionGroup&gt; Component</h3>
  <p>Items inside the &lt;TransitionGroup&gt; component are animated when they are created or removed.</p>
  <button @click="addDie">Roll</button>
  <button @click="addDie10">Roll 10 dice</button>
  <button @click="dice.sort(compareFunc)">Sort</button>
  <button @click="dice.sort(shuffleFunc)">Shuffle</button><br>
  <TransitionGroup>
    <div v-for="x in dice" :key="x.keyNmbr" class="diceDiv" :style="{ backgroundColor: 'hsl(' + x.dieNmbr * 60 + ',85%,85%)' }" @click="removeDie(x.keyNmbr)">
      {{ x.dieNmbr }}
    </div>
  </TransitionGroup>
</template>

<script>
export default {
  data() {
    return {
      dice: [],
      keyNumber: 0
    };
  },
  methods: {
    addDie() {
      const newDie = {
        dieNmbr: Math.ceil(Math.random() * 6),
        keyNmbr: this.keyNumber
      };
      this.dice.splice(Math.floor(Math.random() * this.dice.length), 0, newDie);
      this.keyNumber++;
    },
    addDie10() {
      for (let i = 0; i < 10; i++) {
        this.addDie();
      }
    },
    compareFunc(a, b) {
      return a.dieNmbr - b.dieNmbr;
    },
    shuffleFunc(a, b) {
      return Math.random() - 0.5;
    },
    removeDie(key) {
      const pos = this.dice.map(e => e.keyNmbr).indexOf(key);
      this.dice.splice(pos, 1);
    }
  },
  mounted() {
    this.addDie10();
  }
};
<\/script>

<style>
  .v-enter-from {
    opacity: 0;
    scale: 0;
    rotate: 360deg;
  }
  .v-enter-to {
    opacity: 1;
    scale: 1;
    rotate: 0deg;
  }
  .v-enter-active,
  .v-leave-active,
  .v-move {
    transition: all 0.7s;
  }
  .v-leave-active {
    position: absolute;
  }
  .v-leave-from {
    opacity: 1;
  }
  .v-leave-to {
    opacity: 0;
  }
  .diceDiv {
    margin: 10px;
    width: 30px;
    height: 30px;
    line-height: 30px;
    vertical-align: middle;
    text-align: center;
    border: solid black 1px;
    border-radius: 5px;
    display: inline-block;
  }
  .diceDiv:hover {
    cursor: pointer;
    box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
  }
  #app {
    position: relative;
  }
<\/style>

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

نکته: همیشه برای آیتم های v-for، ویژگی key بگذار. این کار، ردیابی و انیمیشن را دقیق می کند.

جمع بندی سریع

  • <TransitionGroup> ظرف انیمیشن های v-for است.
  • برای هر آیتم، کلید یکتا بده.
  • کلاس v-move جابجایی بقیه را نرم می کند.
  • position: absolute; در خروج، جا را خالی می کند.
  • سرعت را با transition کنترل کن.

بیشتر بخوان: انیمیشن با v-for، انیمیشن ها در Vue.