[Vuejs]-Using parameters for computed functions in Vue

0👍

You can do this with a method. Here’s an example:

<template>
  <ul>
    <li>Total games played: {{ countWhere('isPlayed', true) }}</li>
    <li>Total video games: {{ countWhere('type', 'video') }}</li>
  </ul>
</template>
export default {
  data() {
    return {
      gameList: [
        { name: 'doom', type: 'video', isPlayed: true },
        { name: 'chess', type: 'board', isPlayed: true },
        { name: 'checkers', type: 'board', isPlayed: false },
        { name: 'fortnite', type: 'video', isPlayed: true },
      ],
    };
  },
  methods: {
    countWhere(key, value) {
      return this.gameList.filter(game => game[key] === value).length;
    },
  },
};

0👍

You cannot use computed with parameters (well, technically you can by using “hack” returning new function from computed property but then it works like a normal method…just dirty and confusing). Using method as David suggest sure works but methods are really not effective because they are called every time template is re-rendered and you want to make your app as fast and effective as possible, right ?

Do this:

<template>
  <ul>
    <li>Total games played: {{ gamesStats.totalGames }}</li>
    <li>Total video games: {{ gamesStats.videoGames }}</li>
  </ul>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      gameList: [
        { name: "doom", type: "video", isPlayed: true },
        { name: "chess", type: "board", isPlayed: true },
        { name: "checkers", type: "board", isPlayed: false },
        { name: "fortnite", type: "video", isPlayed: true }
      ],
      stats: {
        totalGames: item => (item.isPlayed ? 1 : 0),
        videoGames: item => (item.type === "video" ? 1 : 0)
      }
    };
  },
  computed: {
    gamesStats() {
      const entries = Object.entries(this.stats);

      // initialise aggregator with zeroes...
      const aggregator = {};
      entries.forEach(([key, func]) => (aggregator[key] = 0));

      this.gameList.reduce(function(acc, item) {
        entries.forEach(function([key, func]) {
          acc[key] += func(item);
        });
        return acc;
      }, aggregator);

      return aggregator;
    }
  }
};
</script>

Now your gamesStats is recomputed only when something changes in gameList array (not on every re-render) and you can do more interesting things, not just compare object key to some fixed value.

And as a bonus, you have a nice clean template without unnecessary JS code..

Leave a comment