Vue, настройка строк таблицы данных на основе даты

#javascript #vue.js #vuejs2

Вопрос:

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

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

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

 Employee  |  2021-08-31  |  2021-09-01  |  2021-09-02
-----------------------------------------------------
Evan        60                60
Stan        100               200
Kelly       60                             164
 

Как я могу изменить то, что я делаю, чтобы у меня была только одна строка на сотрудника, и поместить данные в правильный столбец на основе даты заголовка столбца и даты в объекте для этой записи?

 <div id="app">
  <table>
    <thead>
      <tr>
        <th>Employee</th>
        <th>2021-08-31</th>
        <th>2021-09-01</th>
        <th>2021-09-02</th>
        <th>Grand Total</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(row, index) in compRows">
        <td v-html="row.employee"></td>
        <td v-if="row.workDate == {{$date->addDay()->format($format)}}"></td>
        <td v-html="row.hours"></td>
      </tr>
    </tbody>
  </table>
</div>


@endsection

@section('loadjs')

<script>

new Vue({
  el: "#app",
  data: {
    rows: [
        {  
            employee: "Evan",
            hours: "15",
            workDate: "2021-08-31",
            swipes: "4",
            
        },
        {  
            employee: "Kelly",
            hours: "15",
            workDate: "2021-08-31",
            swipes: "4",
            
        },
        {  
            employee: "Evan",
            hours: "15",
            workDate: "2021-09-01",
            swipes: "4",
           
        },
        {  
            employee: "Stan",
            hours: "25",
            workDate: "2021-08-31",
            swipes: "4",
            
        },
        {  
            employee: "Kelly",
            hours: "82",
            workDate: "2021-09-02",
            swipes: "2",
            
        },
        {  
            employee: "Stan",
            hours: "40",
            workDate: "2021-09-01",
            swipes: "5",
           
        }
    ]
  },
  methods: {

  },
  computed: {
    compRows() {
      const grouped = this.rows.reduce((r, o) => {
        r[o.employee] ??= {};
        r[o.employee][o.workDate] ??= {employee: o.employee, workDate: o.workDate, swipes: 0, hours: 0};
        r[o.employee][o.workDate].swipes  =  o.swipes;
        r[o.employee][o.workDate].hours  =  o.hours;
        return r;
      }, {});
      return Object.values(grouped).map(o => Object.values(o)).flat();
    }
  }
});


</script>
 

Ответ №1:

  1. Вместо того чтобы сгруппировать данные в compRows реквизите (переименованном ниже как hoursByEmployee ), сохраните его в качестве объекта для поиска сотрудников по часам по дате позже. Кроме того, отследите свойство, в котором хранится общая сумма (по часам). total
     export default {
      computed: {
        hoursByEmployee() {
          return this.rows.reduce((r, o) => {
            r[o.employee] ??= {}
            r[o.employee][o.workDate] ??= {swipes: 0, hours: 0}
            r[o.employee][o.workDate].swipes  =  o.swipes
            r[o.employee][o.workDate].hours  =  o.hours
            r[o.employee].total ??= 0 👈
            r[o.employee].total  = ( o.swipes *  o.hours) 👈
            return r
          }, {})
        },
      }
    }
     
  2. Используйте другое вычисляемое свойство , чтобы получить доступные даты из строк workDate , отсортированных в хронологическом порядке:
     export default {
      computed: {
        dates() {
          const dates = [...new Set(this.rows.map(r => r.workDate))]
          return dates.sort((a,b) => new Date(a) - new Date(b))
        },
      }
    }
     
  3. В заголовке таблицы шаблона отобразите вычисленный dates :
     <thead>
      <tr>
        <th>Employee</th>
        <th v-for="date in dates" :key="date">{{ date }}</th> 👈
        <th>Grand Total</th>
      </tr>
    </thead>
     
  4. В теле таблицы шаблона отобразите вычисленные часы работы сотрудников по дате, используя hoursByEmployee поиск и dates созданный выше. Если для даты существуют часы, отобразите общее количество дней. Кроме того, отобразите свойство grand total в последнем столбце.
     <tbody>
      <tr v-for="(hours, employee) in hoursByEmployee" :key="employee">
        <td>{{ employee }}</td>
        <td v-for="date in dates" :key="date">{{ hours[date] amp;amp; hours[date].swipes * hours[date].hours }}</td> 👈
        <td>{{ hours.total }}</td> 👈
      </tr>
    </tbody>
     

ДЕМОНСТРАЦИЯ

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

1. Это невероятно полезный и обстоятельный ответ, спасибо! Мало того, что это работает, но я сразу понял, почему шел в неправильном направлении с выравниванием. Все это время я предполагал, что мне нужно будет сгладить, но, когда я углубился в это, я понял, что мне нужен другой подход, и, похоже, это все. Еще раз спасибо!