首页 文章

在vue.js中的数组中的项目渲染转换之间进行延迟

提问于
浏览
0

我在vuejs中使用vuex从json服务中加载一组项目 . 项目将被带到一个数组并在另一个组件中呈现 . 我尝试使用过渡组为项目单独添加过渡 . 但它没有用 . 所以我正在考虑逐项渲染项目和淡入淡出,并且需要在一个项目和其他项目之间进行延迟 . 我的代码如下

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>

1 回答

  • 1

    使用 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>
    <span class="description">{{ item.description }}</span> </li> </transition-group> </div>

相关问题