vue中延迟一个组件的渲染

Far*_*sen 2 vuejs2

我在 vue 中创建了一个组件,它包装了一个 vue-apexchart 甜甜圈图。一旦页面加载并加载了这个组件,vue-apexchart 就会动画并显示一个小图形。现在我想从一个数据集中并排实例化多个这些组件。而不是所有组件同时加载动画,我想要一个小的渲染延迟来给它一个整体不错的效果。这样的事情会很好:

  <donut :items="series1"></donut>
  <donut :items="series2" delay=1500></donut>
Run Code Online (Sandbox Code Playgroud)

vue-apexchart 不支持初始化延迟,据我所知,目前没有任何针对 vue 的官方解决方案来延迟组件的渲染。我尝试在任何组件挂钩中放置一个 setTimeout 以停止初始化,我还尝试在 setTimeout 的 v-html 标签上的模板元素中注入所有图形 DOM,但是 apexchart 没有注意到这一点新的 dom 内容,vue 也没有注意到 html 绑定。

我创建了这个加载图形的两个实例的小提琴:https : //jsfiddle.net/4f2zkq5c/7/

有什么创意建议吗?

Sov*_*ina 10

如果您可以重新格式化数据,则可以构建一个系列对象数组,添加一个show: true/false属性并迭代它:

//template
<div v-for="serie in series">
  <donut :items="serie.data" v-if="serie.show"></donut>
</div>

//script
data: function() {
  return {
    series: [
      { data: [44, 55, 41, 17, 15], show: false },
      { data: [10, 20, 30], show: false },
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以创建一个setTimeout函数,该函数将serie.show通过true根据系列索引增加延迟来更改 。
然后在挂载的钩子上添加函数:

methods: {
  delayedShow (serie, idx) {
    let delay = 1500 * idx
    setTimeout(() => {
      serie.show = true
    }, delay)
  }
},
mounted () {
  this.series.forEach((serie, idx) => {
    this.delayedShow(serie, idx)
  })
}
Run Code Online (Sandbox Code Playgroud)

实例


Ter*_*rry 8

有几种方法可以做到这一点,这取决于您是否可以实际修改 <animated-component>自己逻辑:

1.使用VueJS的内置<transition-group>处理列表渲染

VueJS 为转换提供了非常方便的支持,您可以使用它来顺序显示您的<animated-component>. 您将需要使用自定义动画库(如 VelocityJS)并简单地将延迟存储在元素的数据集中,例如v-bind:data-delay="500". VueJS 文档有一个很好的例子,说明如何为 引入交错转换<transition-group>,下面的例子很大程度上改编自它。

然后使用beforeAppearappear钩子设置 的各个子项的不透明度<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)
    }
  }
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

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'
    }
  }
});
Run Code Online (Sandbox Code Playgroud)
.animated-component {
  transition: opacity 0.25s ease-in-out;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • @Farsen 这就是为什么在您的问题中包含 MCVE 很重要的原因:在您的原始问题中,没有说明您面临哪些限制,更不用说您正在使用什么库了。 (2认同)