Vue,通过数据对象中的索引值计算 属性 到 add/multiply

Vue, computed property to add/multiply by indexed value in data object

我现在正在使用计算 属性 来尝试对我的 vue 对象数据中的值求和,但是,它目前只是对每个行条目进行求和,我想尝试按员工分组.我的最终目标是能够通过对每位员工的扫描来增加工作时间,但现在我只是想弄清楚如何利用我已经在做的事情,但通过 destinct 员工对其进行索引,以便每个员工只有一个 table 前端行。

我做错了什么?

<?php 
use Carbon\Carbon;
$format = 'Y-m-d';
$date = Carbon::now();
?>

<div id="app">
  <table>
    <thead>
      <tr>
        <th>Employee</th>
        <th>{{$date->format($format)}}</th>
        <th>{{$date->addDay()->format($format)}}</th>
        <th>{{$date->addDay(1)->format($format)}}</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(row, index) in rows">
        <td v-html="row.employee"></td>
        <td v-html="totalRequest"></td>
        <td v-html="totalRequest"></td>
        <td v-html="totalRequest"></td>
      </tr>
    </tbody>
  </table>

</div>


<script>

  new Vue({
  el: "#app",
  data: {
    rows: [
        {  
            employee: "A123",
            hours: "15",
            date: "2021-08-31",
            scans: "4"

        },
        {  
            employee: "A123",
            hours: "25",
            date: "2021-08-31",
            scans: "4"
            
        },
        {  
            employee: "D432",
            hours: "82",
            date: "2021-09-02",
            scans: "2"
            
        },
        {  
            employee: "D432",
            hours: "40",
            date: "2021-09-01",
            scans: "5"
        }
    ]
  },
  methods: {
    
  },
  computed: {
    totalRequest() {
      return this.rows.reduce((acc, item) => acc + item.hours, 0);
    }
  }
});
</script>

创建一个方法来按姓名对员工进行分组,然后映射对象值以获取总数:

  methods: {
    groupByField(list, field)  {
    const result = {};
    list.forEach(item => {
      const value = item[field];
      if (value) {
        if (!result[value]) {
          result[value] = [];
        }
        result[value].push(item);
      }
    });
    return result;
  }
  },
  computed: {
    compRows() {
     const  a=this.groupByField(this.rows,'employee');
    let b=Object.values(a)
    return b.map(item=>{
            return { employee:item[0].employee,hours:item.reduce((acc, _item) => (+acc) + (+_item.hours), 0), scans:item.reduce((acc, _item) => (+acc) + (+_item.scans), 0),date:item[0].date}
    })
    }
  }

在模板中

 <tr v-for="(row, index) in compRows">
        <td >{{row.employee}}</td>
        <td >{{row.hours}}</td>
          <td >{{row.scans}}</td>
       <td >{{row.date}}</td>
      </tr>

完整示例

Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
  el: "#app",
  data: {
    rows: [{
        employee: "A123",
        hours: "15",
        date: "2021-08-31",
        scans: "4"

      },
      {
        employee: "A123",
        hours: "25",
        date: "2021-08-31",
        scans: "4"

      },
      {
        employee: "D432",
        hours: "82",
        date: "2021-09-02",
        scans: "2"

      },
      {
        employee: "D432",
        hours: "40",
        date: "2021-09-01",
        scans: "5"
      }
    ]
  },
  methods: {
    groupByField(list, field) {
      const result = {};
      list.forEach(item => {
        const value = item[field];
        if (value) {
          if (!result[value]) {
            result[value] = [];
          }
          result[value].push(item);
        }
      });
      return result;
    }
  },
  computed: {
    compRows() {
      const a = this.groupByField(this.rows, 'employee');
      let b = Object.values(a)
      return b.map(item => {
        return {
          employee: item[0].employee,
          hours: item.reduce((acc, _item) => (+acc) + (+_item.hours), 0),
          scans: item.reduce((acc, _item) => (+acc) + (+_item.scans), 0),
          date: item[0].date
        }
      })
    }
  }
});
th,td{
padding:8px
}
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>


<div id="app" class="container">
  <table class="table">
    <thead>
      <tr>
        <th>Employee</th>
        <th>hours</th>
        <th>scans</th>
        <th>date</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(row, index) in compRows">
        <td>{{row.employee}}</td>
        <td>{{row.hours}}</td>
        <td>{{row.scans}}</td>
        <td>{{row.date}}</td>
      </tr>
    </tbody>
  </table>
</div>

以下是您可以添加到组件中计算对象的计算方法

  groupedUser() {
      let group_users = {};
      this.rows.forEach(item => {
        const value = item['employee'];
        if (value) {
          if (!group_users[value]) {
            group_users[value] = [];
          }
          group_users[value].push(item);
        }
      });
      let group_users_array =Object.values(group_users)
      return group_users_array.map(item=>{
            return { 
              employee:item[0].employee,
              hours:item.reduce((acc, _item) => (+acc) + (+_item.hours), 0),
              scans:item.reduce((acc, _item) => (+acc) + (+_item.scans), 0),
              date:item[0].date
            }
      })
    }

在 HTML 部分中,您需要将 groupedUser 循环为

 <tr v-for="(row, index) in groupedUser">
        <td v-html="row.employee"></td>
        <td v-html="totalRequest"></td>
        <td v-html="totalRequest"></td>
        <td v-html="totalRequest"></td>
      </tr>

Working Example