Есть несколько способов сделать это, и это зависит от того, можете ли вы действительно изменить логику <animated-component>
самостоятельно:
1.Используйте встроенный <transition-group>
VueJS для обработки рендеринга списка
VueJS поставляется с очень удобной поддержкой переходов, которые вы можете использовать для последовательного отображения <animated-component>
.Вам нужно будет использовать собственную библиотеку анимации (например, VelocityJS) и просто сохранить задержку в наборе данных элемента, например, v-bind:data-delay="500"
. Документы VueJS имеют очень хороший пример того, как вводить ступенчатые переходы для <transition-group>
, и приведенный ниже пример в значительной степени адаптирован из него.
Затем вы используете beforeAppear
и appear
hooks для установки непрозрачности отдельных дочерних элементов <transition-group>
.
Vue.component('animated-component', {
template: '#animatedComponentTemplate',
props: {
data: {
required: true
}
}
});
new Vue({
el: '#app',
data: {
dataset: {
first: 'Hello world',
second: 'Foo bar',
third: 'Lorem ipsum'
}
},
methods: {
beforeAppear: function(el) {
el.style.opacity = 0;
},
appear: function(el, done) {
var delay = +el.dataset.delay;
setTimeout(function() {
Velocity(
el, {
opacity: 1
}, {
complete: done
}
)
}, delay)
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<transition-group name="fade" v-on:before-appear="beforeAppear" v-on:appear="appear">
<animated-component v-bind:data="dataset.first" v-bind:key="0"> </animated-component>
<animated-component v-bind:data="dataset.second" v-bind:key="1" v-bind:data-delay="500"> </animated-component>
<animated-component v-bind:data="dataset.third" v-bind:key="2" v-bind:data-delay="1000"> </animated-component>
</transition-group>
</div>
<script type="text/x-template" id="animatedComponentTemplate">
<div>
<h1>Animated Component</h1>
{{ data }}
</div>
</script>
2.Пусть <animated-component>
обрабатывает собственный рендеринг
В этом примере вы просто передаете число в свойство delay
(не забудьте использовать v-bind:delay="<number>"
, чтобы передать число, а не строку).Затем в подключенном хуке жизненного цикла <animated-component>
вы используете таймер для переключения видимости самого компонента.
Техника, как вы хотите показать изначально скрытый компонент, зависит от вас, ноздесь я просто применяю начальную непрозрачность 0
и затем изменяю ее после setTimeout.
Vue.component('animated-component', {
template: '#animatedComponentTemplate',
props: {
data: {
required: true
},
delay: {
type: Number,
default: 0
}
},
data: function() {
return {
isVisible: false
};
},
computed: {
styleObject: function() {
return {
opacity: this.isVisible ? 1 : 0
};
}
},
mounted: function() {
var that = this;
window.setTimeout(function() {
that.isVisible = true;
}, that.delay);
}
});
new Vue({
el: '#app',
data: {
dataset: {
first: 'Hello world',
second: 'Foo bar',
third: 'Lorem ipsum'
}
}
});
.animated-component {
transition: opacity 0.25s ease-in-out;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<animated-component v-bind:data="dataset.first"> </animated-component>
<animated-component v-bind:data="dataset.second" v-bind:delay="500"> </animated-component>
<animated-component v-bind:data="dataset.third" v-bind:delay="1000"> </animated-component>
</div>
<script type="text/x-template" id="animatedComponentTemplate">
<div class="animated-component" v-bind:style="styleObject">
<h1>Animated Component, delay: {{ delay }}</h1>
{{ data }}
</div>
</script>