入室/退出とリスト遷移
目次
- ##明示的なトランジション期間##JavaScriptフック
- ##複数の遷移要素
- 移行モード複数のコンポーネントの移行
- リスト遷移
- リストの入退出遷移 再利用可能なトランジション
- 動的トランジション
Vue DOM を挿入、更新、または削除するときに、トランジション効果を適用するさまざまな方法を提供します。
次のツールが含まれています:
- で使用できますAnimate.css などのサードパーティの CSS アニメーション ライブラリと組み合わせて使用します。 #Velocity.js などのサードパーティの JavaScript アニメーション ライブラリで使用できます
- ここでは、入場、退出、リストの遷移についてのみ説明します。次のセクション 遷移状態の管理
- 。
- #単一要素/コンポーネントのトランジション
を提供しますのカプセル化されたコンポーネントを使用すると、次の状況で任意の要素またはコンポーネントにエントリ/離脱遷移を追加できます。
条件付きレンダリング (v-if を使用)
条件付き表示 (v-show
を使用)
動的コンポーネント
コンポーネントルートノード
これは典型的な例です:
<div id="demo"> <button v-on:click="show = !show"> Toggle </button> <transition name="fade"> <p v-if="show">hello</p> </transition> </div>
new Vue({ el: '#demo', data: { show: true } })
.fade-enter-active, .fade-leave-active { transition: opacity .5s; } .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { opacity: 0; }
transition
コンポーネントに含まれる要素を挿入または削除するとき、Vue
1.対象要素にCSSトランジションやアニメーションが適用されているかどうかを自動的に嗅ぎ分け、適用されている場合は適切なタイミングでCSSクラス名を追加/削除します。
2. 遷移コンポーネントが JavaScript フック関数 を提供する場合、これらのフック関数は適切なタイミングで呼び出されます。
3. JavaScript フックが見つからず、CSS 遷移/アニメーションが検出されなかった場合は、次のフレームで直ちに DOM 操作 (挿入/削除) が実行されます。 (注: これはブラウザのフレームごとのアニメーション メカニズムを指し、Vue の nextTick
概念とは異なります)
# #遷移クラス名
入場・退出の遷移中に6回のクラス切り替えが発生します。 1.v-enter: 遷移に入る開始状態を定義します。これは要素が挿入される前に有効になり、要素が挿入された後の次のフレームで削除されます。
v-enter-active: エントリ遷移が有効になるときの状態を定義します。トランジション全体に適用され、要素が挿入される前に有効になり、トランジション/アニメーションの完了後に削除されます。このクラスは、遷移を入力するための処理時間、遅延、および曲線関数を定義するために使用できます。
v-enter-to:
バージョン 2.1.8 以降 トランジションに入る終了状態を定義します。要素が挿入された後の次のフレームで有効になり (同時に v-enter が削除されます)、トランジション/アニメーションが完了した後に削除されます。
v-leave: 離脱遷移の開始状態を定義します。これは、離脱トランジションがトリガーされるとすぐに有効になり、次のフレームで削除されます。
v-leave-active: 離脱遷移が有効になるときの状態を定義します。終了トランジション全体に適用され、終了トランジションがトリガーされるとすぐに有効になり、トランジション/アニメーションが完了すると削除されます。このクラスを使用して、処理時間、遅延、終了遷移の曲線関数を定義できます。
v-leave-to:
バージョン 2.1.8 以降 Leave 遷移の終了状態を定義します。 Leave トランジションがトリガーされた後の次のフレームで有効になり (同時に v-leave が削除されます)、トランジション/アニメーションの完了後に削除されます。
<transition> を使用すると、
v - は、これらのクラス名のデフォルトの接頭辞です。
<transition name="my-transition"> を使用すると、
v-enter は
my-transition-enter に置き換えられます。
v-enter-active
と v-leave-active
は、次のセクションに示すように、エントリー/リーブ遷移のさまざまなイージング カーブを制御できます。
CSS トランジション
一般的に使用されるトランジションでは CSS トランジションが使用されます。
これは簡単な例です:
<div id="example-1"> <button @click="show = !show"> Toggle render </button> <transition name="slide-fade"> <p v-if="show">hello</p> </transition> </div>
new Vue({ el: '#example-1', data: { show: true } })
/* 可以设置不同的进入和离开动画 */ /* 设置持续时间和动画函数 */ .slide-fade-enter-active { transition: all .3s ease; } .slide-fade-leave-active { transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0); } .slide-fade-enter, .slide-fade-leave-to /* .slide-fade-leave-active for below version 2.1.8 */ { transform: translateX(10px); opacity: 0; }
#CSS アニメーション #CSS アニメーションの使い方は CSS トランジションと同じですが、アニメーションでは v-enter
クラス名はノードが DOM に挿入された直後には削除されませんが、animationend になります。イベントがトリガーされると削除されます。
例: (互換性プレフィックスは省略)
<div id="example-2"> <button @click="show = !show">Toggle show</button> <transition name="bounce"> <p v-if="show">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis enim libero, at lacinia diam fermentum id. Pellentesque habitant morbi tristique senectus et netus.</p> </transition> </div>
new Vue({ el: '#example-2', data: { show: true } })
.bounce-enter-active { animation: bounce-in .5s; } .bounce-leave-active { animation: bounce-in .5s reverse; } @keyframes bounce-in { 0% { transform: scale(0); } 50% { transform: scale(1.5); } 100% { transform: scale(1); } }
次の機能を使用して遷移クラス名をカスタマイズできます:
#enter-class##アクティブクラスに入る
(2.1.8 )クラスに入る
leave-active-class
(2.1.8)leave-to-class
一緒に使用すると非常に便利です。これらは通常のクラス名よりも高い優先順位を持ち、Vue のトランジション システムや、
などの他のサードパーティ CSS アニメーション ライブラリに役立ちます。 Animate.css
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css"> <div id="example-3"> <button @click="show = !show"> Toggle render </button> <transition name="custom-classes-transition" enter-active-class="animated tada" leave-active-class="animated bounceOutRight" > <p v-if="show">hello</p> </transition> </div>rrree
Vue が遷移の完了を認識するには、対応するイベント リスナーを設定する必要があります。要素に適用される CSS ルールに応じて、transitionend または animationend になります。これらのいずれかを使用すると、Vue は自動的に型を認識し、リスナーを設定できます。
ただし、シナリオによっては、同じ要素に 2 つのトランジション アニメーションを同時に設定する必要があります。たとえば、animation
はトリガーされてすぐに完了しますが、transition
効果はまだ終わっていません。この場合、
属性を使用し、animation
または transition
を設定して、Vue がリッスンするタイプを明示的に宣言する必要があります。 #明示的な移行期間
2.2.0 New 多くの場合、Vue はトランジション エフェクトの完了時間を自動的に決定できます。デフォルトでは、Vue はトランジション エフェクトのルート要素で最初の この場合、 開始と終了の期間をカスタマイズすることもできます: JavaScript フック JavaScript フックは次のことができます。 これらのフック関数は、CSS JavaScript のみを使用して遷移する場合、enter v-bind:css="false"transitionend
または animationend
イベントを待ちます。ただし、これを行うことは不可能です。たとえば、ネストされた内部要素の一部のトランジションがトランジションのルート要素と比較して遅延または長い場合、注意深く振り付けられた一連のトランジションを作成することはできます。 <transition>
コンポーネントの duration
プロパティを使用して、明示的な遷移期間 (ミリ秒単位) をカスタマイズできます。 new Vue({
el: '#example-3',
data: {
show: true
}
})
<transition :duration="1000">...</transition>
<transition :duration="{ enter: 500, leave: 800 }">...</transition>
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled"
>
<!-- ... -->
</transition>
transitions/animations
と組み合わせて使用することも、単独で使用することもできます。 および
leave のコールバックには
done
を使用する必要があります。それ以外の場合、それらは同期的に呼び出され、移行はすぐに完了します。 JavaScript トランジションのみを使用する要素に
Velocity.js を使用した簡単な例: を追加することをお勧めします。Vue は CSS 検出をスキップします。これにより、遷移中の CSS の影響も回避されます。
// ...
methods: {
// --------
// 进入中
// --------
beforeEnter: function (el) {
// ...
},
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
enter: function (el, done) {
// ...
done()
},
afterEnter: function (el) {
// ...
},
enterCancelled: function (el) {
// ...
},
// --------
// 离开时
// --------
beforeLeave: function (el) {
// ...
},
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
leave: function (el, done) {
// ...
done()
},
afterLeave: function (el) {
// ...
},
// leaveCancelled 只用于 v-show 中
leaveCancelled: function (el) {
// ...
}
}
<!--
Velocity 和 jQuery.animate 的工作方式类似,也是用来实现 JavaScript 动画的一个很棒的选择
-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<div id="example-4">
<button @click="show = !show">
Toggle
</button>
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:leave="leave"
v-bind:css="false"
>
<p v-if="show">
Demo
</p>
</transition>
</div>
##初期遷移レンダリングの
最初のレンダリングでのノードの遷移は、Apply
属性
を使用して設定できます。ここでのデフォルトは次のとおりです。入退室遷移と同様にCSSクラス名もカスタマイズできます。 new Vue({
el: '#example-4',
data: {
show: false
},
methods: {
beforeEnter: function (el) {
el.style.opacity = 0
el.style.transformOrigin = 'left'
},
enter: function (el, done) {
Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
Velocity(el, { fontSize: '1em' }, { complete: done })
},
leave: function (el, done) {
Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 })
Velocity(el, { rotateZ: '100deg' }, { loop: 2 })
Velocity(el, {
rotateZ: '45deg',
translateY: '30px',
translateX: '30px',
opacity: 0
}, { complete: done })
}
}
})
<transition appear> <!-- ... --> </transition>
カスタム JavaScript フック:
<transition appear appear-class="custom-appear-class" appear-to-class="custom-appear-to-class" (2.1.8+) appear-active-class="custom-appear-active-class" > <!-- ... --> </transition>
上記の例では、
Appearl 属性と v-on:Appearance
フックの両方が生成されます。初期レンダリング遷移。
##複数のコンポーネントについては後で説明します。遷移 、ネイティブ タグの場合は、
v-if/v-elseを使用できます。最も一般的なマルチラベル トランジションは、リストと、リストが空であるというメッセージを記述する要素です。
<transition
appear
v-on:before-appear="customBeforeAppearHook"
v-on:appear="customAppearHook"
v-on:after-appear="customAfterAppearHook"
v-on:appear-cancelled="customAppearCancelledHook"
>
<!-- ... -->
</transition>
は次のように使用できますが、注意すべき点が 1 つあります。
例:同じタグ名 を持つ 要素が切り替えられている場合、Vue がそれらを区別できるように、
key
属性を通じて一意の値を設定してマークを付ける必要があります。それ以外の場合、Vue は同じタグ内のコンテンツのみを置換します。技術的に必要ではない場合でも、<transition>コンポーネント内の複数の要素にキーを設定することをお勧めします
。
<transition> <table v-if="items.length > 0"> <!-- ... --> </table> <p v-else>Sorry, no items found.</p> </transition>一部のシナリオでは、代わりに同じ要素の
key 属性に異なる状態を設定することもできます
v-if と
v-else の場合、上記の例は次のように書き換えることができます。
<transition> <button v-if="isEditing" key="save"> Save </button> <button v-else key="edit"> Edit </button> </transition>複数の
v-if を使用した複数の要素の遷移は、単一として書き換えることができます動的プロパティがバインドされた要素の遷移。たとえば:
<transition> <button v-bind:key="isEditing"> {{ isEditing ? 'Save' : 'Edit' }} </button> </transition>は次のように書き換えることができます:
<transition> <button v-if="docState === 'saved'" key="saved"> Edit </button> <button v-if="docState === 'edited'" key="edited"> Save </button> <button v-if="docState === 'editing'" key="editing"> Cancel </button> </transition>
<transition> <button v-bind:key="docState"> {{ buttonMessage }} </button> </transition>
##移行モードここには別の問題があります。次のボタンをクリックしてみてください。
「オン」ボタンと「オフ」ボタンの間の遷移で、両方のボタンが再描画され、一方のボタンは再描画されます。一方がトランジションを終了し、もう一方がトランジションに入り始めます。これは
のデフォルトの動作です - 開始と終了は同時に発生します。 要素が互いに完全に重なって配置されている場合は正常に動作します:
次に、移動を追加して、スライド トランジションのように要素を移動させます:
同時に有効になるトランジションの開始と終了はすべての要件を満たすことができないため、Vue は
- ##in-out
- : 新しい要素が最初に遷移し、次に現在の要素が遷移します。
- : 現在の要素が最初に遷移し、次に新しい要素が遷移します。
前のスイッチ ボタンのトランジションを out-in
// ... computed: { buttonMessage: function () { switch (this.docState) { case 'saved': return 'Edit' case 'edited': return 'Save' case 'editing': return 'Cancel' } } }
シンプルな機能を 1 つ追加するだけですこれにより、追加のコードを必要とせずに以前の移行の問題が解決されます。
in-out
モードはあまり頻繁には使用されませんが、わずかに異なるトランジション効果には依然として役立ちます。前のスライドアウトの例を組み合わせる:
すごいと思いませんか?
複数のコンポーネントの移行
複数のコンポーネントの移行ははるかに簡単です。キー##を使用する必要はありません。 # 属性。代わりに、
動的コンポーネント:
<transition name="fade" mode="out-in"> <!-- ... the buttons ... --> </transition>
<transition name="component-fade" mode="out-in"> <component v-bind:is="view"></component> </transition>
new Vue({ el: '#transition-components-demo', data: { view: 'v-a' }, components: { 'v-a': { template: '<div>Component A</div>' }, 'v-b': { template: '<div>Component B</div>' } } })
##listを使用する必要があります。移行
これまで、移行について説明してきました:- 単一ノード
- 複数のノードの 1 つを同時にレンダリングする
- では、
を使用するなどして、リスト全体を同時にレンダリングするにはどうすればよいでしょうか?このシナリオでは、<transition-group>
コンポーネントを使用します。例に入る前に、このコンポーネントのいくつかの機能を理解しましょう:
- <transition>
とは異なり、実際の要素としてレンダリングされます: デフォルト
<スパン>
の場合。tag
属性を使用して、他の要素に置き換えることもできます。 - 移行モード 内部要素
- では、常に
が一意の key 属性値を提供する必要があります。
CSS 遷移クラスは、グループ/コンテナ自体ではなく、内部要素に適用されます。
次に For から始めましょう簡単な例では、入口と出口の遷移では前と同じ CSS クラス名が使用されます。
.component-fade-enter-active, .component-fade-leave-active { transition: opacity .3s ease; } .component-fade-enter, .component-fade-leave-to /* .component-fade-leave-active for below version 2.1.8 */ { opacity: 0; }
<div id="list-demo" class="demo"> <button v-on:click="add">Add</button> <button v-on:click="remove">Remove</button> <transition-group name="list" tag="p"> <span v-for="item in items" v-bind:key="item" class="list-item"> {{ item }} </span> </transition-group> </div>
new Vue({ el: '#list-demo', data: { items: [1,2,3,4,5,6,7,8,9], nextNum: 10 }, methods: { randomIndex: function () { return Math.floor(Math.random() * this.items.length) }, add: function () { this.items.splice(this.randomIndex(), 0, this.nextNum++) }, remove: function () { this.items.splice(this.randomIndex(), 1) }, } })
この例には問題があります。要素を追加および削除すると、周囲の要素はスムーズに移行するのではなく、即座に新しいレイアウト位置に移動します。この問題は以下で解決してください。
#リストの遷移のソート
<transition-group> コンポーネントもう一つの特別な機能があります。アニメーションに出入りできるだけでなく、位置を変更することもできます。この新機能を使用するには、新しい
v-move 機能
について知っておくだけで済みます。この機能は、要素の位置を変更するプロセス中に適用されます。前のクラス名と同様に、プレフィックスは name 属性を使用してカスタマイズすることも、
move-class 属性を使用して手動で設定することもできます。 v-move
は、切り替えタイミングとトランジションの遷移曲線を設定するのに非常に便利です。次の例が表示されます。
.list-item { display: inline-block; margin-right: 10px; } .list-enter-active, .list-leave-active { transition: all 1s; } .list-enter, .list-leave-to /* .list-leave-active for below version 2.1.8 */ { opacity: 0; transform: translateY(30px); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script> <div id="flip-list-demo" class="demo"> <button v-on:click="shuffle">Shuffle</button> <transition-group name="flip-list" tag="ul"> <li v-for="item in items" v-bind:key="item"> {{ item }} </li> </transition-group> </div>
new Vue({ el: '#flip-list-demo', data: { items: [1,2,3,4,5,6,7,8,9] }, methods: { shuffle: function () { this.items = _.shuffle(this.items) } } })
これは素晴らしいですね。内部的には、Vue は FLIP
という単純なアニメーション キューを使用します。変換を使用して要素を以前の位置から移動します。新しい位置へのスムーズな移行場所。
以前に実装した例とこのテクノロジを組み合わせて、リスト内のすべての変更にアニメーションによる遷移が行われるようにします。
.flip-list-move { transition: transform 1s; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script> <div id="list-complete-demo" class="demo"> <button v-on:click="shuffle">Shuffle</button> <button v-on:click="add">Add</button> <button v-on:click="remove">Remove</button> <transition-group name="list-complete" tag="p"> <span v-for="item in items" v-bind:key="item" class="list-complete-item" > {{ item }} </span> </transition-group> </div>
new Vue({ el: '#list-complete-demo', data: { items: [1,2,3,4,5,6,7,8,9], nextNum: 10 }, methods: { randomIndex: function () { return Math.floor(Math.random() * this.items.length) }, add: function () { this.items.splice(this.randomIndex(), 0, this.nextNum++) }, remove: function () { this.items.splice(this.randomIndex(), 1) }, shuffle: function () { this.items = _.shuffle(this.items) } } })
FLIP トランジションを使用する要素は
display: inline
に設定できないことに注意してください。代わりに、display: inline-block
に設定するか、フレックス
FLIP アニメーションで単一列の遷移だけでなく、多次元グリッドも実現できます。 は遷移も可能です :
##リストの段階的な遷移# data 属性を介して JavaScript と通信することで、リストの段階的な遷移を実現できます。
.list-complete-item { transition: all 1s; display: inline-block; margin-right: 10px; } .list-complete-enter, .list-complete-leave-to /* .list-complete-leave-active for below version 2.1.8 */ { opacity: 0; transform: translateY(30px); } .list-complete-leave-active { position: absolute; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script> <div id="staggered-list-demo"> <input v-model="query"> <transition-group name="staggered-fade" tag="ul" v-bind:css="false" v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:leave="leave" > <li v-for="(item, index) in computedList" v-bind:key="item.msg" v-bind:data-index="index" >{{ item.msg }}</li> </transition-group> </div>
##再利用可能なトランジション
トランジションは、Vue のコンポーネント システムを通じて再利用できます。再利用可能なトランジション コンポーネントを作成するには、<transition>
または<transition-group>
をルート コンポーネントとして作成し、その中に子コンポーネントを配置するだけです。 。 テンプレートを使用した簡単な例:
new Vue({ el: '#staggered-list-demo', data: { query: '', list: [ { msg: 'Bruce Lee' }, { msg: 'Jackie Chan' }, { msg: 'Chuck Norris' }, { msg: 'Jet Li' }, { msg: 'Kung Fury' } ] }, computed: { computedList: function () { var vm = this return this.list.filter(function (item) { return item.msg.toLowerCase().indexOf(vm.query.toLowerCase()) !== -1 }) } }, methods: { beforeEnter: function (el) { el.style.opacity = 0 el.style.height = 0 }, enter: function (el, done) { var delay = el.dataset.index * 150 setTimeout(function () { Velocity( el, { opacity: 1, height: '1.6em' }, { complete: done } ) }, delay) }, leave: function (el, done) { var delay = el.dataset.index * 150 setTimeout(function () { Velocity( el, { opacity: 0, height: 0 }, { complete: done } ) }, delay) } } })
機能コンポーネント
は、このタスクを完了するのに適しています:
Vue.component('my-special-transition', { template: '\ <transition\ name="very-special-transition"\ mode="out-in"\ v-on:before-enter="beforeEnter"\ v-on:after-enter="afterEnter"\ >\ <slot></slot>\ </transition>\ ', methods: { beforeEnter: function (el) { // ... }, afterEnter: function (el) { // ... } } })
動的トランジション
Vue のトランジションもデータ駆動型です。動的遷移の最も基本的な例は、name
属性を使用して動的値をバインドすることです。Vue.component('my-special-transition', { functional: true, render: function (createElement, context) { var data = { props: { name: 'very-special-transition', mode: 'out-in' }, on: { beforeEnter: function (el) { // ... }, afterEnter: function (el) { // ... } } } return createElement('transition', data, context.children) } })
これは、Vue のトランジション システムを使用して CSS トランジション/アニメーションを定義し、さまざまなトランジションを切り替える場合に便利です。
すべての遷移プロパティは動的にバインドできますが、イベント フックはすべてメソッドであるため、使用できるプロパティがあるだけでなく、イベント フックを介してコンテキスト内のすべてのデータを取得することもできます。これは、JavaScript トランジションがコンポーネントの状態に応じて異なる動作をすることを意味します。 リーリーリーリー
最後に、動的なトランジションを作成するための最後の解決策は、コンポーネントが props を受け入れることによって前のトランジションを動的に変更することです。古いことわざにあるように、唯一の制限はあなたの想像力です。