Skip to content

الانتقال

توفر Vue مكونين مدمجين يمكنهما المساعدة في التعامل مع الانتقالات والتحريكات استجابةً لتغيير الحالة:

  • المكون <Transition> لتطبيق التحريكات عندما يُدخل عنصر أو مكون إلى الـDOM أو إخراجه. ستغطى في هذه الصفحة.

  • المكون <TransitionGroup> لتطبيق التحريكات عندما يدرج عنصر أو مكون في قائمة v-for أو إزالته أو نقله. سيغطى في الفصل التالي.

بصرف النظر عن هذين المكونين ، يمكننا أيضًا تطبيق التحريكات في Vue باستخدام تقنيات أخرى مثل تبديل أصناف CSS أو التحريكات المدفوعة بالحالة عبر ربط التنسيقات تغطى هذه التقنيات الإضافية في فصل تقنيات التحريك.

المكون <Transition>

<Transition> هو مكون مدمج: هذا يعني أنه متاح في قالب أي مكون دون الحاجة إلى تسجيله. يمكن استخدامه لتطبيق تحريكات الدخول والخروج على العناصر أو المكونات التي مُررت إليه عبر منفذه الافتراضي. يمكن تشغيل الدخول أو الخروج بواسطة إحدى الطرق الموالية:

  • التصيير الشرطي عبر v-if
  • العرض الشرطي عبر v-show
  • تبديل المكونات الديناميكية عبر عنصر <component> الخاص
  • تغيير السمة الخاصة key

هذا مثال على الاستخدام الأساسي الشائع:

template
<button @click="show = !show">تبديل</button>
<Transition>
  <p v-if="show">مرحبا</p>
</Transition>
css
/* سنشرح ما تفعله هذه الأصناف في الفصل التالي! */
.v-enter-active,
.v-leave-active {
  transition: opacity 0.5s ease;
}

.v-enter-from,
.v-leave-to {
  opacity: 0;
}

مرحبا

ملاحظة

<Transition> يدعم فقط عنصر واحد أو مكونًا كمحتوى للمنفذ. إذا كان المحتوى هو مكون ، يجب أن يكون المكون أيضًا له عنصر جذر واحد فقط.

عند إدراج عنصر في مكون <Transition> أو إزالته ، يحدث ما يلي:

  1. ستقوم Vue تلقائيًا بفحص ما إذا كان العنصر المستهدف له انتقالات أو تحريكات CSS مطبقة. إذا كان الأمر كذلك ، فسيضاف / يزال عدد من أصناف انتقال CSS في توقيتات مناسبة.

  2. إذا كان هناك مستمعون لـ الخطافات البرمجية لـJavascript ، فستستدعى هذه الخطافات في توقيتات مناسبة.

  3. إذا لم تكتشف أي انتقالات / تحريكات CSS ولم توفر خطافات JavaScript ، فستنفذ عمليات DOM للإدراج و / أو الإزالة في إطار التحريكات التالي للمتصفح.

الانتقالات المعتمدة على الـCSS

أصناف الانتقال

There are six classes applied for enter / leave transitions.

هناك ستة أصناف تطبق لانتقالات الدخول / الخروج.

Transition Diagram

  1. v-enter-from: بدء الحالة للدخول. يضاف قبل إدراج العنصر، ويزال إطارًا واحدًا بعد إدراج العنصر.

  2. v-enter-active: حالة نشطة للدخول. تطبق خلال مرحلة الدخول بأكملها. يضاف قبل إدراج العنصر، ويزال عندما ينتهي الانتقال / التحريك. يمكن استخدام هذا الصنف لتحديد المدة والتأخير ومنحنى التخفيف للانتقال الداخل.

  3. v-enter-to: حالة الانتهاء للدخول. يضاف إطارًا واحدًا بعد إدراج العنصر (في نفس الوقت يزال v-enter-from) ، ويزال عندما ينتهي الانتقال / التحريك.

  4. v-leave-from: بدء الحالة للخروج. يضاف على الفور عند تشغيل انتقال الخروج ، ويزال بعد إطار واحد.

  5. v-leave-active: حالة نشطة للخروج. تطبق خلال مرحلة الخروج بأكملها. يضاف على الفور عند تشغيل انتقال الخروج ، ويزال عندما ينتهي الانتقال / التحريك. يمكن استخدام هذا الصنف لتحديد المدة والتأخير ومنحنى التخفيف للانتقال الخارج.

  6. v-leave-to: حالة الانتهاء للخروج. يضاف إطارًا واحدًا بعد تشغيل انتقال الخروج (في نفس الوقت يزال v-leave-from) ، ويزال عندما ينتهي الانتقال / التحريك.

v-enter-active و v-leave-active تمنحنا القدرة على تحديد منحنيات التخفيف المختلفة لانتقالات الدخول / الخروج ، والتي سنرى مثالًا عليها في الأقسام التالية.

الانتقالات المسماة

يمكن تسمية الانتقال عبر خاصية name:

template
<Transition name="fade">
  ...
</Transition>

بالنسبة لانتقال مسمى، ستضاف أصناف الانتقال الخاصة به مع بادئة اسمه بدلاً من v. على سبيل المثال، سيكون الصنف المطبق للانتقال أعلاه fade-enter-active بدلاً من v-enter-active. يجب أن يبدو CSS لانتقال التلاشي مثل هذا:

css
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

انتقالات الـCSS

<Transition> يستخدم عادةً بالتزامن مع انتقالات الـCSS الأصلية، كما هو موضح في المثال الأساسي أعلاه. خاصية transition في الـCSS هي اختصار يسمح لنا بتحديد جوانب متعددة من الانتقال، بما في ذلك الخصائص التي يجب تحريكها، ومدة الانتقال، ومنحنيات التخفيف.

فيما يلي مثال متقدم تنتقل فيه خاصيات متعددة، مع مدد مختلفة ومنحنيات تخفيف للدخول والخروج:

template
<Transition name="slide-fade">
  <p v-if="show">مرحبا</p>
</Transition>
css
/*
 يمكن للانتقالات الداخلة والخارجة 
استخدام مدد ودوال توقيت مختلفة. 
*/
.slide-fade-enter-active {
  transition: all 0.3s ease-out;
}

.slide-fade-leave-active {
  transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);
}

.slide-fade-enter-from,
.slide-fade-leave-to {
  transform: translateX(20px);
  opacity: 0;
}

مرحبا

تحريكات الـCSS

تحريكات الـCSS الأصلية تُطبق بنفس طريقة تحريكات الـCSS، مع الفرق في أن *-enter-from لا تُزال على الفور بعد إدراج العنصر، ولكن عند حدوث حدث animationend.

بالنسبة لمعظم تحريكات الـCSS، يمكننا ببساطة تعريفها تحت فئات enter-active-* و leave-active-*. هذا مثال:

template
<Transition name="bounce">
  <p v-if="show" style="text-align: center;">
        مرحبا هنا بعض النص النطاط!
  </p>
</Transition>
css
.bounce-enter-active {
  animation: bounce-in 0.5s;
}
.bounce-leave-active {
  animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.25);
  }
  100% {
    transform: scale(1);
  }
}

مرحبا هنا بعض النص النطاط!

أصناف انتقال مخصصة

يمكنك أيضًا تحديد أصناف انتقال مخصصة عن طريق تمرير الخاصيات التالية إلى <Transition>:

  • enter-from-class
  • enter-active-class
  • enter-to-class
  • leave-from-class
  • leave-active-class
  • leave-to-class

هذا سيتجاوز أسماء الأصناف التقليدية. هذا مفيد بشكل خاص عندما تريد دمج نظام انتقال Vue مع مكتبة تحريك CSS موجودة مسبقًا ، مثل Animate.css:

template
<!-- نفترض أن Animate.css مضمنة في الصفحة -->
<Transition
  name="custom-classes"
  enter-active-class="animate__animated animate__tada"
  leave-active-class="animate__animated animate__bounceOutRight"
>
  <p v-if="show">مرحبا</p>
</Transition>

استخدام الانتقالات و التحريكات معا

تحتاج Vue إلى إضافة مستمعين للأحداث لمعرفة متى ينتهي الانتقال. يمكن أن يكون إما transitionend أو animationend ، اعتمادًا على نوع قواعد CSS المطبقة. إذا كنت تستخدم أحدهما فقط ، فيمكن لـ Vue اكتشاف النوع الصحيح تلقائيًا.

و مع ذلك ، في بعض الحالات قد ترغب في الحصول على كلاهما على نفس العنصر ، على سبيل المثال وجود تحريك CSS يشغل بواسطة Vue ، جنبًا إلى جنب مع تأثير انتقال CSS في حالة التحويم. في هذه الحالات ، سيتعين عليك إعلان النوع الذي تريد أن يهتم Vue به صراحة عن طريق تمرير خاصية type ، بقيمة إما animation أو transition:

template
<Transition type="animation">...</Transition>

انتقالات متداخلة ومدد انتقالية صريحة

بالرغم من أن أصناف الانتقال تُطبق فقط على العنصر الابن المباشر في <Transition> ، يمكننا تطبيق الانتقال على العناصر المتداخلة باستخدام محددات CSS المتداخلة:

template
<Transition name="nested">
  <div v-if="show" class="outer">
    <div class="inner">
      مرحبا
    </div>
  </div>
</Transition>
css
/* قواعد تستهدف العناصر المتداخلة */
.nested-enter-active .inner,
.nested-leave-active .inner {
  transition: all 0.3s ease-in-out;
}

.nested-enter-from .inner,
.nested-leave-to .inner {
  transform: translateX(30px);
  opacity: 0;
}

/* ... القواعد الأخرى غير اللازمة محذوفة */

يمكننا حتى إضافة تأخير انتقال إلى العنصر المتداخل عند الدخول ، مما يخلق تسلسل تحريك دخول متداخل:

css
/* تأخير دخول العنصر المتداخل لتأثير متسلسل */
.nested-enter-active .inner {
  transition-delay: 0.25s;
}

ومع ذلك ، هذا يخلق مشكلة صغيرة. بشكل افتراضي ، يحاول عنصر <Transition> تحديد متى انتهى الانتقال تلقائيًا عن طريق الاستماع إلى أول حدث transitionend أو animationend على عنصر الانتقال الجذر. مع انتقال متداخل ، يجب أن يكون السلوك المطلوب الانتظار حتى تنتهي الانتقالات لجميع العناصر الداخلية.

في مثل هذه الحالات ، يمكنك تحديد مدة انتقال صريحة (بالجزء من الثانية) باستخدام خاصية duration على عنصر <transition>. يجب أن تتطابق المدة الإجمالية مع التأخير بالإضافة إلى مدة الانتقال للعنصر الداخلي:

template
<Transition :duration="550">...</Transition>
مرحبا

اختبرها في حقل التجارب

إذا لزم الأمر ، يمكنك أيضًا تحديد قيم منفصلة لمدة الدخول والخروج باستخدام كائن:

template
<Transition :duration="{ enter: 500, leave: 800 }">...</Transition>

اعتبارات الأداء

قد تلاحظ أن التحريكات الموضحة أعلاه تستخدم في الغالب خصائص مثل transform و opacity. هذه الخصائص فعالة في التحريكات لأن:

  1. لا تؤثر على تخطيط المستند أثناء التحريك ، لذلك لا تؤدي إلى حساب تخطيط CSS المكلف في كل إطار تحريك.

  2. يمكن لمعظم المتصفحات الحديثة الاستفادة من تسريع وحدة معالجةالرسوميات GPU عند تحريك transform.

بالمقارنة، خاصيات مثل height أو margin ستؤدي إلى تخطيط CSS ، لذلك فهي أكثر تكلفة للتحريك ، ويجب استخدامها بحذر. يمكننا التحقق من موارد مثل CSS-Triggers لمعرفة الخصائص التي ستؤدي إلى تخطيطها إذا قمنا بتحريكها.

الخطافات البرمجية للتJavascript

يمكنك الانتقال إلى عملية التحويل مع JavaScript عن طريق الاستماع إلى الأحداث على عنصر <Transition>:

html
<Transition
  @before-enter="onBeforeEnter"
  @enter="onEnter"
  @after-enter="onAfterEnter"
  @enter-cancelled="onEnterCancelled"
  @before-leave="onBeforeLeave"
  @leave="onLeave"
  @after-leave="onAfterLeave"
  @leave-cancelled="onLeaveCancelled"
>
  <!-- ... -->
</Transition>
js
// تستدعى قبل إدراج العنصر في DOM.
// استخدم هذا لتعيين حالة "enter-from" للعنصر
function onBeforeEnter(el) {}

// تستدعى إطار واحد بعد إدراج العنصر.
// استخدم هذا لبدء تحريك الدخول.
function onEnter(el, done) {
  // استدع دالة رد النداء   done للإشارة إلى نهاية الانتقال 
  // اختياري إذا استخدم بالتزامن مع CSS
  done()
}

// تستدعى عندما ينتهي انتقال الدخول.
function onAfterEnter(el) {}

// called when the enter transition is cancelled before completion.
function onEnterCancelled(el) {}

// تستدعى قبل خطاف الخروج.
// في معظم الأوقات ، يجب عليك فقط استخدام خطاف الخروج
function onBeforeLeave(el) {}

// تستدعى عند بدء انتقال الخروج.
// استخدم هذا لبدء تحريك الخروج.
function onLeave(el, done) {
  // استدع دالة رد النداء   done للإشارة إلى نهاية الانتقال 
  // اختياري إذا استخدم بالتزامن مع CSS
  done()
}

// تستدعى عندما ينتهي انتقال الخروج وأزيل العنصر من DOM.

function onAfterLeave(el) {}

// تتوفر فقط مع انتقالات v-show
function onLeaveCancelled(el) {}
js
export default {
  // ...
  methods: {
    // تستدعى قبل إدراج العنصر في DOM.
    // استخدم هذا لتعيين حالة "enter-from" للعنصر
    onBeforeEnter(el) {},

    // تستدعى إطار واحد بعد إدراج العنصر.
    // استخدم هذا لبدء التحريك.
    onEnter(el, done) {
      // استدع دالة رد النداء   done للإشارة إلى نهاية الانتقال
      // اختياري إذا استخدم بالتزامن مع CSS
      done()
    },

    // تستدعى عندما ينتهي انتقال الدخول.
    onAfterEnter(el) {},
    onEnterCancelled(el) {},

    // تستدعى قبل خطاف الخروج.
    // في معظم الأوقات ، يجب عليك فقط استخدام خطاف الخروج
    onBeforeLeave(el) {},

    // تستدعى عند بدء انتقال الخروج.
    // استخدم هذا لبدء تحريك الخروج.
    onLeave(el, done) {
      // استدع دالة رد النداء   done للإشارة إلى نهاية الانتقال
      // اختياري إذا استخدم بالتزامن مع CSS
      done()
    },

    // تستدعى عندما ينتهي انتقال الخروج وأزيل العنصر من DOM.

    onAfterLeave(el) {},

    // تتوفر فقط مع انتقالات v-show
    onLeaveCancelled(el) {}
  }
}

يمكن استخدام هذه الخطافات بالتزامن مع انتقالات / تحريكات CSS أو بمفردها.

عند استخدام انتقالات JavaScript فقط ، من المفيد عادة إضافة خاصية :css="false" . هذا يخبر Vue بشكل صريح بتخطي كشف انتقال CSS التلقائي. بصرف النظر عن كونها أكثر قليلا في الأداء ، فإن هذا أيضًا يمنع قواعد CSS من التدخل عن طريق الخطأ مع الانتقال:

template
<Transition
  ...
  :css="false"
>
  ...
</Transition>

مع "css="false: ، نحن أيضًا مسؤولون بالكامل عن التحكم في متى ينتهي الانتقال. في هذه الحالة ، يتطلب استدعاء دالة رد النداء done لخطافات enter@ و leave@ . وإلا ، ستستدعى الخطافات بشكل متزامن وسينتهي الانتقال على الفور.

هذا عرض توضيحي باستخدام مكتبة GreenSock لتنفيذ التحريكات. يمكنك ، بالطبع ، استخدام أي مكتبة تحريكات أخرى تريدها ، على سبيل المثال Anime.js أو Motion One.

انتقالات قابلة لاعادة الاستخدام

يمكن إعادة استخدام الانتقالات من خلال نظام المكونات في فيو. لإنشاء انتقال قابل لإعادة الاستخدام ، يمكننا إنشاء مكون يلف مكون <Transition> ويمرر محتوى الفتحة:

vue
<!-- MyTransition.vue -->
<script>
//  شيفرة خطافات الـJavascript
</script>

<template>
  <!-- غلف المكون المدمج Transition -->
  <Transition
    name="my-transition"
    @enter="onEnter"
    @leave="onLeave">
    <slot></slot> <!-- مرر محتوى المنفذ -->
  </Transition>
</template>

<style>
/* 
  CSS ضروري...
  ملاحظة: تجنب استخدام <style scoped> هنا لأنها
  لا تنطبق على محتوى المنفذ.
*/
</style>

الآن يمكن استيراد MyTransition واستخدامه تمامًا مثل الإصدار المدمج:

template
<MyTransition>
  <div v-if="show">مرحبا</div>
</MyTransition>

الانتقال عند الظهور

إذا كنت تريد أيضًا تطبيق انتقال على التصيير الأولي لعنصر ، يمكنك إضافة خاصية appear:

template
<Transition appear>
  ...
</Transition>

الانتقال بين العناصر

بالإضافة إلى تبديل عنصر مع v-if / v-show ، يمكننا أيضًا الانتقال بين عنصرين باستخدام v-if / v-else / v-else-if ، طالما تأكدنا من أن هناك عنصر واحد فقط يعرض في أي لحظة:

template
<Transition>
  <button v-if="docState === 'saved'">تعديل</button>
  <button v-else-if="docState === 'edited'">حفظ</button>
  <button v-else-if="docState === 'editing'">الغاء</button>
</Transition>
انقر للتنقل بين الحالات:

اختبرها في حقل التجارب

أوضاع الانتقال

في المثال السابق ، تحرك العناصر الداخلة والخارجة في نفس الوقت ، وكان علينا جعلها position: absolute لتجنب مشكلة التخطيط عندما يتواجد كلا العنصرين في DOM.

ومع ذلك ، في بعض الحالات هذا ليس خيارًا ، أو ببساطة ليست السلوك المطلوب. قد نريد تحريك العنصر الخارج أولاً ، وأن يدرج العنصر الداخل بعد انتهاء التحريكات الخارجية. سيكون تنسيق مثل هذه التحريكات يدويًا معقدًا للغاية - لحسن الحظ ، يمكننا تمكين هذا السلوك عن طريق تمرير خاصية mode للمكون <Transition> :

template
<Transition mode="out-in">
  ...
</Transition>

هنا المثال السابق مع "mode="out-in:

انقر للتنقل بين الحالات:

يدعم <Transition> أيضًا "mode="in-out ، على الرغم من أنه يستخدم قليلا.

الانتقال بين المكونات

يمكن أيضًا استخدام <Transition> حول المكونات الديناميكية:

template
<Transition name="fade" mode="out-in">
  <component :is="activeComponent"></component>
</Transition>
Component A

الانتقالات الديناميكية

خاصيات <Transition> مثل name يمكن أن تكون ديناميكية أيضاً! تسمح لنا بتطبيق انتقالات مختلفة بناءً على تغيير الحالة:

template
<Transition :name="transitionName">
  <!-- ... -->
</Transition>

هذا يمكن أن يكون مفيداً عندما تقوم بتعريف انتقالات / تحريكات CSS باستخدام اصطلاحات صنف الانتقال في Vue وتريد التبديل بينهم.

يمكنك أيضاً تطبيق سلوك مختلف في خطافات الانتقال البرمجية بناءً على الحالة الحالية لمكونك. أخيراً، الطريقة القصوى لإنشاء انتقالات ديناميكية هي من خلال مكونات الانتقال القابلة لإعادة الاستخدام التي تقبل خاصيات لتغيير طبيعة الانتقالات المستخدمة. قد يبدو ذلك مبالغاً فيه، لكن الحد الوحيد هو خيالك.


ذات صلة

الانتقال has loaded