admin管理员组

文章数量:1287867

I'm trying to display a list of items on an event's agenda.

The event has a start_date end each item on the agenda has a duration in minutes, for example:

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}
  ]
}

Now, in my event ponent, I load agendas with a v-for:

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

In agenda ponent, I want to increment the time at which each item starts:

<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>

Currently it only adds to the fixed event start_date... I would like to show the times 14:00 for event 1, 14:10 for event 2, 14:25 for event 3 and 14:50 for event 4.

How can I increment the value in a v-for directive in Vue.js 2.0?

I'm trying to display a list of items on an event's agenda.

The event has a start_date end each item on the agenda has a duration in minutes, for example:

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}
  ]
}

Now, in my event ponent, I load agendas with a v-for:

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

In agenda ponent, I want to increment the time at which each item starts:

<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>

Currently it only adds to the fixed event start_date... I would like to show the times 14:00 for event 1, 14:10 for event 2, 14:25 for event 3 and 14:50 for event 4.

How can I increment the value in a v-for directive in Vue.js 2.0?

Share Improve this question edited Mar 2, 2017 at 18:31 BassMHL asked Mar 2, 2017 at 18:15 BassMHLBassMHL 9,05710 gold badges52 silver badges67 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

It looks like you already got an answer that works for you but I'll post this here in case anyone is looking for an alternate solution. The accepted answer might be good for an initial render of the agendas but will start to break if the agendas array is mutated or anything causes the list to re-render because the start time calculation is based on a stored value that gets incremented every iteration.

The code below adds a puted property (based on event.agendas) that returns a new array of of agenda objects, each with an added start property.

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

new Vue({
  el: "#root",
  data: {...}, 
  puted: {
    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;
    }
  }
});

Then, in the template, the agendas_with_start puted property is used in the 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>

Here's a working codepen. The benefit of this approach is that if the underlying agendas array is mutated or re-ordered or the event start time changes or anything causes Vue to re-render the DOM, this puted property will be re-evaluated and the start times will be re-calculated correctly.

Vue.js will actually let you bind prop values to methods on the parent's scope, so the easiest way will be to do something like this:

<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>

And then the get_start_time() is a method within the parent's scope:

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;
    },
  },
});

I've made a quick CodePen as a basic example to show it in action, but you'll need to update the actual code to pensate for multiple days.

本文标签: javascriptVuejs vfor increment some variable in looped componentStack Overflow