I'm loading a set of items from a json service calling using vuex in vuejs. Items will be taken to a array and render in a different component. I tried using transition-group to add a transition seperately for a item. But it did not work. So i'm thinking of rendering item and fadeIn item by item and need to make a delay between one item and other item. My code is below
ProductItem.vue
<template>
<transition name="slide-fade">
<div class="product-container">
<div class="product-box">
<div class="product-image">
<img v-bind:src="product.values['3'].value" alt>
</div>
<div class="product-details">
<div class="product-name">{{product.values[0].value}}</div>
<div class="product-description" v-if="product" v-html="productDescription"></div>
<div class="product-price">From 295 LKR</div>
<div class="product-action">
<button class="btn-choose" @click="closeBox">
<i class="fas fa-check fa-icon"></i> Choose
</button>
</div>
</div>
</div>
</div>
</transition>
</template>
Products.vue
<template>
<div>
<div class="product-list-container clearfix">
<div v-if="!hasProducts">
<product-item-loader v-for="itemLoader in 8" v-bind:key="itemLoader"></product-item-loader>
</div>
<transition name="fade">
<div v-if="hasProducts">
<product-item v-for="pItem in productsList" :product="pItem" v-bind:key="pItem"></product-item>
</div>
</transition>
</div>
</div>
</template>
<script>
import productItem from "./ProductItem.vue";
import productItemLoader from "./ProductItemLoader.vue";
export default {
components: {
productItem,
productItemLoader
},
data() {
return {
iconCalendar:
"M39.58,115.5h70.84a7.11,7.11,0,0,0,7.08-7.08V48.21a7.11,7.11,0,0,0-7.08-7.09H99.79V34a3.54,3.54,0,0,0-7.08,0v7.08H57.29V34a3.54,3.54,0,1,0-7.08,0v7.08H39.58a7.11,7.11,0,0,0-7.08,7.09v60.21A7.11,7.11,0,0,0,39.58,115.5Zm0-67.29H50.21v3.54a3.54,3.54,0,0,0,7.08,0V48.21H92.71v3.54a3.54,3.54,0,0,0,7.08,0V48.21h10.63V62.38H39.58Zm0,21.25h70.84v39H39.58Z",
productsList: [],
hasProducts: false,
date: "2012-12-01"
};
},
methods: {
optionChanged: function(selection) {
this.getProducts(selection.name);
},
getProducts: function(date) {
self = this;
self.hasProducts = false;
this.restAPI
.get("", {
params: {
after: date,
until: date,
language: "en"
}
})
.then(function(response) {
self.productsList = response.data.content.classes[0].objects;
self.productsList.length > 0
? (self.hasProducts = true)
: (self.hasProducts = false);
})
.catch(e => {
console.log(e);
});
}
},
beforeMount() {
self.hasProducts = false;
this.getProducts();
}
};
</script>
You can achieve a nice staggered effect by using setInterval
:
new Vue({ el: '#app', data() { return { loading: false, items: [], remaining: 3000 } }, mounted() { this.loading = true const timer = () => { return setInterval(() => { this.remaining -= 1000 }, 1000) } // simulate api call const ti = timer() setTimeout(() => { const items = Array.from(Array(9), (x, i) => { return { name: `Product ${i + 1}`, description: `Product ${i + 1} description` } }) clearInterval(ti) this.loading = false const interval = setInterval(() => { if (!items.length) { clearInterval(interval) } else { this.items.push(items.shift()) } }, 360) }, 3000) }, methods: { renderNext(item) { this.items.push(item) } } })
li { width: 30%; padding: .3rem; } li.striped { background-color: rgba(128,203,196,.4); } .list-complete-item { transition: all 1s; display: inline-block; margin-right: 0px; } .list-complete-enter, .list-complete-leave-to /* .list-complete-leave-active below version 2.1.8 */ { opacity: 0; transform: translateY(30px); } .list-complete-leave-active { position: absolute; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <h1 v-if="loading">Loading... {{ remaining / 1000 }}</h1> <transition-group name="list-complete" tag="ul"> <li v-for="(item, i) in items" v-bind:key="item.name" :class="`list-complete-item ${i % 2 === 0 ? 'striped' : ''}`"> <span>{{ item.name }}</span><br/> <span class="description">{{ item.description }}</span> </li> </transition-group> </div>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.