Вопрос или проблема
В настоящее время у меня на блэйд-файле отображается прошедшее время. Однако, чтобы увидеть обновлённое время, мне нужно обновлять страницу каждый раз. Я хотел бы отображать динамически изменяющееся время. Есть ли способ это сделать?
Мой текущий код состоит в том, что я передаю 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
.
Шаги для реализации
-
Создайте переменную для хранения времени: Вместо того, чтобы возвращать строку непосредственно из метода
setTimer
, лучше будет создать реактивное свойство, которое будет хранить оставшееся время и обновляться каждые несколько секунд. -
Используйте
setInterval
: Настройте интервал, который будет обновлять оставшееся время. Это можно сделать в методеmounted
, чтобы когда ваш компонент будет смонтирован, обновление началось автоматически. -
Очистите интервал: Когда компонент будет уничтожен, обязательно очистите интервал, чтобы предотвратить утечки памяти.
Пример кода
Вот обновленная версия вашего 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()
: Этот метод используется для принудительного обновления компонента и перерисовки его данных. Он не рекомендуется к частому использованию, однако в данном случае, когда время обновляется каждую секунду, это приемлемый подход. -
Логика вычислений: Используется простая логика для вычисления прошедшего времени, которая преобразует общее количество секунд в часы, минуты и секунды.
-
Очистка интервала: Важно очищать интервалы при разрушении компонента для предотвращения утечек памяти и наложения нескольких экземпляров таймеров.
Заключение
С помощью вышеописанного подхода вы сможете динамически обновлять отображаемое время без необходимости обновления страницы. Убедитесь, что этот код соответствует вашему основному приложению и возможно, адаптируйте его для других компонентов, содержащих подобную функциональность.