Задержка рендеринга компонента в vue - PullRequest
0 голосов
/ 08 апреля 2019

Я создал компонент в vue, который упаковывает граф пончиков vue-apexchart.Как только страница загружается и этот компонент загружается, vue-apexchart анимирует и отображает небольшой график.Теперь я хотел бы создать несколько таких компонентов из набора данных рядом.Вместо того, чтобы все компоненты загружали анимацию одновременно, я бы хотел небольшую задержку рендеринга, чтобы получить хороший эффект.Что-то вроде этого было бы неплохо:

  <donut :items="series1"></donut>
  <donut :items="series2" delay=1500></donut>

До сих пор vue-apexchart поддерживает задержки инициализации, и, насколько я вижу, не существует какого-либо конкретного vue-официального решения для задержки рендеринга компонентов.Я пытался поместить setTimeout в любой из хуков компонентов, чтобы остановить инициализацию, я также пытался внедрить DOM всех графов в элементе шаблона в тег v-html в setTimeout, но apexchart до сих пор замечает этоновое содержимое dom и vue doesent также обращают внимание на привязки html.

Я создал эту скрипку, которая загружает два экземпляра графика: https://jsfiddle.net/4f2zkq5c/7/

Любые творческие предложения?

Ответы [ 2 ]

2 голосов
/ 09 апреля 2019

Есть несколько способов сделать это, и это зависит от того, можете ли вы действительно изменить логику <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>
0 голосов
/ 12 апреля 2019

Если у вас есть возможность переформатировать ваши данные, вы можете создать массив объектов серии, добавить свойство 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 },
    ]
  }
}

Теперь вы можете создать функцию 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)
  })
}

Пример в реальном времени

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...