Vue.js v-для увеличения некоторой переменной в циклическом компоненте

Я пытаюсь отобразить список пунктов повестки дня мероприятия.

Событие имеет start_date конец каждого пункта повестки дня имеет duration в минутах, например:

event:{
  start_date: '2017-03-01 14:00:00',
  agendas:[
      {id:1,duration:10},
      {id:2,duration:15},
      {id:3,duration:25},
      {id:4,duration:10}
  ]
}

Теперь по моему event компонент, загружаю agendas с v-for:

<agenda v-for="(agenda,index) in event.agendas" 
        :key="agenda.id"
        :index="index" 
        :agenda="agenda">

В agenda компонент, я хочу увеличить время, в которое начинается каждый элемент:

<div class="agenda">
  //adding minutes to start_date with momentJs library
  {{ moment(event.start_date).add(agenda.duration,'m') }} //this should increment, not add to the fixed event start date
</div>

В настоящее время это только добавляет к фиксированному событию start_date... Я хотел бы показать время 14:00 для события 1, 14:10 для события 2, 14:25 для события 3 а также 14:50 для события 4,

Как я могу увеличить значение в v-for директива в Vue.js 2.0?

2 ответа

Решение

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

Код ниже добавляет вычисляемое свойство (на основе event.agendas), который возвращает новый массив объектов повестки дня, каждый с добавленным start имущество.

Vue.component('agenda', {
  template: '<div>Agenda {{ agenda.id }} — {{ agenda.duration }} min — {{ agenda.start }}</div>',
  props: {
    agenda: Object
  }
});

new Vue({
  el: "#root",
  data: {...}, 
  computed: {
    agendas_with_start() {
      const result = [];

      let start = moment(this.event.start_date);
      for(let agenda of this.event.agendas) {
        result.push({
          id: agenda.id,
          duration: agenda.duration,
          start: start.format('HH:mm')
        });
        start = start.add(agenda.duration, 'm');
      }
      return result;
    }
  }
});

Затем в шаблоне agendas_with_start вычисляемое свойство используется в v-for:

<div id="root">
  <h3>Event Start: {{ event.start_date }}</h3>
  <agenda v-for="agenda in agendas_with_start" 
          :key="agenda.id"
          :agenda="agenda"></agenda>
</div>

Вот рабочий кодекс. Преимущество этого подхода состоит в том, что, если базовый массив повесток дня видоизменен или переупорядочен, или время начала события изменяется, или что-либо заставляет Vue повторно выполнить рендеринг DOM, это вычисленное свойство будет переоценено, и время начала будет повторно - правильно рассчитал.

Vue.js на самом деле позволит вам привязать значения prop к методам в родительской области видимости, поэтому самым простым способом будет сделать что-то вроде этого:

<agenda class="agenda" v-for="(agenda,index) in event.agendas"
    :key="agenda.id"
    :index="index"
    :agenda="agenda"
    :start-time="get_start_time(agenda.duration)">
</agenda>

А потом get_start_time() это метод в пределах родительской области:

new Vue({
  el: '#app',
  data: {
    time_of_day: '',
    event:{
      // ...
    },
  },

  methods: {
    get_start_time(duration) {
      if (this.next_event_start === '') {
        this.next_event_start = moment(this.event.start_date);
      } 
      this.event_start = this.next_event_start.format('h:mm a');
      this.next_event_start.add(duration, 'minutes');
      return this.event_start;
    },
  },
});

Я сделал быстрый CodePen в качестве базового примера, чтобы показать его в действии, но вам нужно будет обновить реальный код, чтобы компенсировать это за несколько дней.

Другие вопросы по тегам