如何在评论中获得总票数,然后取平均值?

How to make the sum of votes in a review, and then the average too?

情况是这样的, 我在 Vue 上下文中,Laravel 作为后端。在我的主页上,我有一个 select 用于根据他们的流派搜索音乐家,所以当我到达此页面时,我想在每张音乐家卡片中显示相对于收到的平均票数的星星。

但我在操作模板内的选票时遇到了问题,并且不知道如何在方法中实际操作。我知道这很简单,但它给我带来了问题。

这是问题的视觉部分,用红色圈出

代码如下:

FilteredMusicians.vue

在这里,我循环遍历从 Laravel 端点获取的音乐家数组,然后为了获得选票,我循环遍历每个 musician.reviews 以获得 review.vote。在这里,我遇到了将所有选票加起来并求出平均值的问题。

<template>
  <div class="container">
    <div class="row py-4">
      <div
        v-for="musician in musicians"
        :key="musician.id"
        class="col-xs-12 col-md-4 col-lg-4 my-4"
      >
        <div class="card">
          <div class="musician-img">
            <img
              :src="'/storage/' + musician.cover"
              :alt="musician.stagename"
            />
          </div>
          <div class="card-body text-center">
            <h5 class="card-title py-2">{{ musician.stagename }}</h5>
            <!-- reviews -->
            <div v-for="review in musician.reviews" :key="review.id">
              {{ review.vote }}
            </div>
            <!-- /reviews -->
            <router-link
              class="btn btn-orange text-white"
              :to="{ name: 'musician', params: { slug: musician.slug } }"
              >Vedi profilo</router-link
            >
          </div>
        </div>
      </div>
    </div>
    <div class="text-center">
      <router-link class="btn btn-orange text-white mb-3" :to="{ name: 'home' }"
        >Indietro</router-link
      >
    </div>
  </div>
</template>

<script>
export default {
  name: "FilteredMusicians",

  data() {
    return {
      musicians: [],
    };
  },

  methods: {
    getMusicians(slug) {
      axios
        .get(`http://127.0.0.1:8000/api/musicians/${slug}`)
        .then((res) => {
          res.data.forEach((el) => {
            this.musicians = el.musicians;
          });
        })
        .catch((err) => {
          console.log(err);
        });
    },

    
  },

  created() {
    this.getMusicians(this.$route.params.slug);
  },
};
</script>

获取与流派相关的所有音乐家的功能

public function filterMusicians($slug) {

        $genres = Genre::where('slug', $slug)->with('musicians')->get();

        return response()->json($genres);
    }

这是 Musician 模型,这里我使用 protected $with 来获取每个流派过滤的音乐家的评论

class Musician extends Model
{
    protected $fillable = [
        'user_id', 
        'stagename',
        'slug', 
        'description',
        'bio',
        'services',
        'typology',
        'cover'
    ]; 

    protected $with = [
        'reviews'
    ];


    public function user() {
        return $this->hasOne('App\User'); 
    }

    public function genres() {
        return $this->belongsToMany('App\Genre'); 
    }

    public function sponsorships() {
        return $this->belongsToMany('App\Sponsorship')->withPivot('end_date'); 
    }

    public function messages() {
        return $this->hasMany('App\Message'); 
    }

    public function reviews() {
        return $this->hasMany('App\Review');
    }
}

和评论模型

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Review extends Model
{
    protected $fillable = [
        'name',  
        'email', 
        'review', 
        'vote', 
        'musician_id'
    ]; 

    public function musician() {
        return $this->belongsTo('App\Musician')->with('reviews'); 
    }
}

我更喜欢 React,但您在这里需要做的似乎很简单。首先在你的 getMusicians 方法下创建一个新方法,你可以将其命名为 getAverageVotes。我想象它看起来像这样:

getAverageVotes(reviews) {
  const sum = reviews.reduce((acc, review) => acc += review.vote, 0)
  return sum / reviews.length
}

在您的模板中,将此更改为:

<div v-for="review in musician.reviews" :key="review.id">
  {{ review.vote }}
</div>

对此:

<div>
  {{ getAverageVotes(musician.reviews) }}
</div>

您只是想计算 music.reviews 的平均值吗?

创建方法。

reviewAvg(reviews: any[]) {
  if (reviews.length == 0) return 0;
  else {
    return reviews.reduce((a, b) => a + b.vote, 0) / reviews.length;
  }
}

然后修改重复投票的代码

{{reviewAvg(musician.reviews}}

如果需要reduce的详细解释,可以参考下面

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce