Как перебирать массив и визуально отображать отдельные элементы в vue

#javascript #typescript #vue.js #vuetify.js

Вопрос:

У меня есть приложение, в котором у меня есть небольшая форма, в которой пользователь может добавить одну дату с несколькими временами начала и окончания, а затем поместить ее в массив. Этот процесс можно повторять столько раз, сколько потребуется.

вот как выглядит этот массив:

 datesFinal: {meetingName: "", meetingPw:"", meetingUrl: "",
      meetingTime: []} ,
 

В поле Дата встречи будет сохранено время начала и окончания. одна форма значения может быть такой:

  "meetingTime":[
      {
         "date":"2021-06-21",
         "startTime":"15:30",
         "endTime":"16:30"
      },
      {
         "date":"2021-06-21",
         "startTime":"15:30",
         "endTime":"17:30"
      },
 

Чего я хочу добиться сейчас, так это чтобы мое приложение просматривало этот массив и смотрело, одинакова ли дата для двух объектов в данном случае два раза 2021.06.21, она должна отображаться следующим образом:

2021.06.21
15:30-17:30 15:30-16:30

Под ним должно быть собрано время, относящееся к одной и той же дате.Я попытался зациклить массив, чтобы сначала показать полный объект без какой-либо фильтрации в качестве начала. Но я получаю ошибку, что она не определена (раз не определена).

Не мог бы кто-нибудь взглянуть на мой код и дать мне указатель:

  <v-col cols="12" v-for="(timesForDate, i) in datesFinal" key="i">
        <h4>{{ datesFinal.meetingTime}}</h4>
        <v-chip-group v-if="time.length">
          <v-chip v-for="(time, j) in datesFinal.meetingTime" :key="j">{{
              time.startTime   ":"   time.endTime
            }}</v-chip>
        </v-chip-group>
      </v-col>
 

Комментарии:

1. Я рекомендую использовать вычисленный для логики вместо внутренних сложных вложенных v-для и v-если

2. что ты имеешь в виду? Я довольно новичок в vue, и мне нужно сделать с ним свою диссертацию

Ответ №1:

Мой совет был бы таков: не пытайтесь решить эту проблему, изменив пользовательский интерфейс. Преобразуйте ваши данные в желаемую структуру, и пусть шаблон повторит простейшую структуру данных, которую вы можете придумать.

 new Vue({
  el: "#app",
  data() {
    return {
      datesFinal: {
        meetingName: "This is the meeting name",
        meetingTime: [{
            "date": "2021-06-21",
            "startTime": "15:30",
            "endTime": "16:30"
          },
          {
            "date": "2021-06-21",
            "startTime": "15:30",
            "endTime": "17:30"
          },
          {
            "date": "2021-06-23",
            "startTime": "15:30",
            "endTime": "16:30"
          },
          {
            "date": "2021-06-22",
            "startTime": "15:30",
            "endTime": "17:30"
          },
          {
            "date": "2021-06-20",
            "startTime": "15:30",
            "endTime": "16:30"
          },
          {
            "date": "2021-06-22",
            "startTime": "15:30",
            "endTime": "17:30"
          },
        ],
      },
    }
  },
  methods: {
    // grouping the meeting times by date
    // the function expects an array of objects
    // with a structure:
    // [{ date: "foo", startTime: "bar", endTime: "baz" },
    // { date: "foo", startTime: "bar3", endTime: "baz3" },
    // { date: "foo2", startTime: "bar2", endTime: "baz2" }]
    // it creates an Object with a structure:
    // { foo: ["bar-baz", "bar3-baz3"], foo2: ["bar2-baz2"] }
    processMeetingTimes(meetingTimeArray) {
      const ret = meetingTimeArray
        .reduce((a, c) => {
          if (!(c.date in a)) a[c.date] = []
          a[c.date] = [...a[c.date], `${c.startTime}-${c.endTime}`]
          return a
        }, {})
      console.log("processMeetingTimes", ret)
      return ret
    },
    // creating the array of strings that the v-for
    // can iterate over easily
    // it expects an Object with a structure:
    // { foo: ["bar-baz", "bar3-baz3"], foo2: ["bar2-baz2"] }
    // and creates an Array with a structure:
    // ["foo bar-baz bar3-baz3", "foo2 bar2-baz2"]
    createMeetingTimeArray(processedMeetingTimes) {
      const ret = Object.entries(processedMeetingTimes).map(([key, val]) => `${key} ${val.join(" ")}`)
      console.log("createMeetingTimeArray", ret)
      return ret
    },
  },
  template: `
    <div>
      {{ datesFinal.meetingName }}
      <div
        v-for="time in createMeetingTimeArray(
          processMeetingTimes(datesFinal.meetingTime)
        )"
        :key="time"
      >
        {{ time }}
      </div>
    </div>
  `
}) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>