Vue JS – Время, прошедшее с даты в режиме реального времени

Вопрос или проблема

В настоящее время у меня на блэйд-файле отображается прошедшее время. Однако, чтобы увидеть обновлённое время, мне нужно обновлять страницу каждый раз. Я хотел бы отображать динамически изменяющееся время. Есть ли способ это сделать?

Мой текущий код состоит в том, что я передаю created_date (определённую из контроллера) в скрипт. Оттуда я получаю часы, минуты и секунды. (Может добавить дни позже). Затем я возвращаю это обратно в свой блэйд-файл.

Это часть из моего блэйд-файла:

<table class="table table-bordered small">
  <thead>
      <tr>
          <th width="2%">№</th>
          <th width="5%">
              Создано
          </th>
      </tr>
  </thead>
  <tbody>
      <tr v-for="(index,row) in records.data" :class="{'NPI_row_color':NPI_Order(row)}">
          <td>@{{index+1}}</td>
          <td>
              @{{ setTimer(row.created_at) }} 
          </td>
      </tr>
  </tbody>
</table>

И это скрипт vue js:

<script type="text/javascript">
  $(function () {
      var vm = new Vue({
          el: '#shopify_marketplace',
          data: {
            //некоторые данные здесь
          },
          methods: {
            //некоторые другие методы здесь
            onReload: function(){
              //несколько строк кода здесь и там
            },
            setTimer: function(created_at){

                const startDate = new Date(created_at);
                const now = new Date();
                const elapsedSeconds = Math.floor((now - startDate) / 1000);

                const day = Math.floor((elapsedSeconds / 3600));
                const hours = Math.floor(elapsedSeconds / 3600);
                const minutes = Math.floor((elapsedSeconds % 3600) / 60);
                const seconds = elapsedSeconds % 60;

                return `${hours}ч ${minutes}м ${seconds}с`;

            },
          },
          filters: {
              autoCaps: function(value){
                  if(value != null) {
                      return value.toLocaleUpperCase();    
                  }
              },
          },
          ready: function () {
              this.onReload();
          },
      });
  });
</script>

Изображение ниже показывает, как сейчас выглядит мой дисплей. Но да, нужно обновлять каждый раз, чтобы увидеть обновление. Могу ли я узнать, как сделать так, чтобы время работало и “тиковало”? Я пытался использовать функцию setInterval из javascript, но мне не удалось.

текущий_дисплей

Ответ или решение

Для решения задачи обновления времени в реальном времени в Vue.js, вам нужно использовать функцию setInterval, которая будет регулярно обновлять значение времени. Ниже представлено решение, которое позволит вам динамически обновлять отображаемое время, основываясь на переданной дате created_at.

Шаги для реализации

  1. Создайте переменную для хранения времени: Вместо того, чтобы возвращать строку непосредственно из метода setTimer, лучше будет создать реактивное свойство, которое будет хранить оставшееся время и обновляться каждые несколько секунд.

  2. Используйте setInterval: Настройте интервал, который будет обновлять оставшееся время. Это можно сделать в методе mounted, чтобы когда ваш компонент будет смонтирован, обновление началось автоматически.

  3. Очистите интервал: Когда компонент будет уничтожен, обязательно очистите интервал, чтобы предотвратить утечки памяти.

Пример кода

Вот обновленная версия вашего Vue.js кода с реализацией динамического обновления времени:

<div id="shopify_marketplace">
    <table class="table table-bordered small">
        <thead>
            <tr>
                <th width="2%">No</th>
                <th width="5%">Created At</th>
            </tr>
        </thead>
        <tbody>
            <tr v-for="(index, row) in records.data" :class="{'NPI_row_color': NPI_Order(row)}">
                <td>@{{ index + 1 }}</td>
                <td>
                    @{{ timeElapsed(row.created_at) }}
                </td>
            </tr>
        </tbody>
    </table>
</div>

<script type="text/javascript">
$(function () {
    var vm = new Vue({
        el: '#shopify_marketplace',
        data: {
            // Некоторые другие данные здесь
            timers: {}
        },
        methods: {
            onReload: function(){
                // Недостающие коды здесь
            },
            timeElapsed: function(created_at){
                const startDate = new Date(created_at);
                const now = new Date();
                const elapsedSeconds = Math.floor((now - startDate) / 1000);

                const hours = Math.floor(elapsedSeconds / 3600);
                const minutes = Math.floor((elapsedSeconds % 3600) / 60);
                const seconds = elapsedSeconds % 60;

                return `${hours}h ${minutes}m ${seconds}s`;
            },
            startTimer: function() {
                const timer = setInterval(() => {
                    this.$forceUpdate(); // Обновление компонента
                }, 1000);
                return timer;
            }
        },
        mounted: function () {
            this.timers.interval = this.startTimer(); // Запуск таймера
            this.onReload();
        },
        beforeDestroy: function () {
            clearInterval(this.timers.interval); // Остановка таймера
        }
    });
});
</script>

Важные замечания

  • $forceUpdate(): Этот метод используется для принудительного обновления компонента и перерисовки его данных. Он не рекомендуется к частому использованию, однако в данном случае, когда время обновляется каждую секунду, это приемлемый подход.

  • Логика вычислений: Используется простая логика для вычисления прошедшего времени, которая преобразует общее количество секунд в часы, минуты и секунды.

  • Очистка интервала: Важно очищать интервалы при разрушении компонента для предотвращения утечек памяти и наложения нескольких экземпляров таймеров.

Заключение

С помощью вышеописанного подхода вы сможете динамически обновлять отображаемое время без необходимости обновления страницы. Убедитесь, что этот код соответствует вашему основному приложению и возможно, адаптируйте его для других компонентов, содержащих подобную функциональность.

Оцените материал
Добавить комментарий

Капча загружается...