Home / Blog / Sorting Lists with Vue.js Composition API Computed Properties
Sorting Lists with Vue.js Composition API Computed Properties

Sorting Lists with Vue.js Composition API Computed Properties

Mostafa Said
Mostafa Said
Updated: August 26th 2024

Vue.js, a popular JavaScript framework, empowers developers to create dynamic and interactive user interfaces. One of its core features, computed properties, plays a vital role in achieving this. Computed properties act as convenient helpers, automatically calculating values based on other reactive data within your components. This keeps your templates clean and your logic organized, making development a breeze.

Now, imagine building a cool quotes app in Vue js 3 with script setup and composition API. To make it even cooler, you want to let users sort the quotes by different criteria. Here's where computed properties come in to play! In this quick tutorial, learn how to leverage computed properties to effortlessly sort lists in Vue.js 3.

Step 1: Fetching Quotes

First things first, we need some quotes! We'll leverage an awesome free API called Quotable to fetch a random set of quotes.

Let’s first have a look at the below code snippet for our Single-File Component (SFC) to be more familiar with the starting point of the tutorial.

<script setup>
    import { ref, onMounted } from 'vue';

    const quotes = ref([]);

    const fetchQuotes = async () => {
      const response = await fetch('https://api.quotable.io/quotes/random?limit=5');
      const data = await response.json();
      quotes.value = data.map((quote) => ({ ...quote, rating: Math.floor(Math.random() * 20) + 1 }));
    };

    onMounted(() => {
      fetchQuotes();
    });
</script>

Here’s a quick explanation:

  • We define a variable ref named quotes to store the fetched quotes.
  • The fetchQuotes function asynchronously fetches data from the Quotable API and parses it into JSON format.
  • We map over the fetched quotes, assigning a random rating between 1 and 20 to each one using Math.floor(Math.random() * 20) + 1.
  • Finally, onMounted ensures fetchQuotes runs automatically when the component mounts.

In the above code snippet, I used Vue.js onMounted hook to trigger the function automatically as soon as the component mounts.

Step 2: Using Computed Properties to Sort The Data

Now comes the exciting part, which is sorting the quotes based on their ratings! To do that, we first need to set the criteria. And for that, we define a variable ref named sortOrder to keep track of the sorting direction (ascending or descending).

const sortOrder = ref('desc');

Then, we need a way to keep an eye on the value of this reactive data. Here's where computed properties shine. We can use Vue.js computed properties to constantly calculate different result whenever the sortOrder variable ref is changed.

We can do that by importing computed API from vue , and define it like this:

const sortedQuotes = computed(() => {
    return console.log('I have my eyes on you, sortOrder! ', sortOrder.value)
});

This computed property now will return the value of sortOrder every time the value changes. This way, we can say “return this value, if the sortOrder.value is desc, and this value if it’s asc”

const sortOrder = ref('desc');

const sortedQuotes = computed(() => {
  if (sortOrder.value === 'desc') {
    return console.log('Sorted in desc');
  } else {
    return console.log('Sorted in asc');
  }
});

Let's move past the demonstration examples and dive into implementing the actual sorting logic. The first thing you need to know about computed properties, is that we shouldn’t use it to trigger side-effects. This means that whatever we want to do with it, it should only be used as a getter.

const sortOrder = ref('desc');

const sortedQuotes = computed(() => {
  const quotesCopy = [...quotes.value];
  if (sortOrder.value === 'desc') {
    return quotesCopy.sort((a, b) => b.rating - a.rating);
  } else {
    return quotesCopy.sort((a, b) => a.rating - b.rating);
  }
});

The sortedQuotes computed property utilizes the power of Vue's reactivity. It creates a copy of the original quotes array quotesCopy to avoid modifying the original data.

Based on the sortOrder.value, the quotes are sorted using JavaScript’s sort function:

  • The sort function takes a callback function that compares two elements (quotes in our case). We want to sort by rating, so we compare b.rating with a.rating.
  • If sortOrder.value is 'desc' (descending), quotes with higher ratings will come first (achieved by subtracting a.rating from b.rating).
  • If sortOrder.value is 'asc' (ascending), quotes with lower ratings will be displayed first (achieved by subtracting b.rating from a.rating).

Now, all we need is a function that toggles the sortOrder value.

const sortQuotes = () => {
  if (sortOrder.value === 'desc') {
    sortOrder.value = 'asc';
  } else {
    sortOrder.value = 'desc';
  }
};

Step 3: Putting it All Together

With our sorted quotes in hand, let's create a user-friendly interface for interacting with them:

<template>
  <div>
    <h1>Random Wise Quotes</h1>

    <button @click="sortQuotes">
      Sort By Rating ({{ sortOrder.toUpperCase() }})
    </button>

    <ul>
      <li v-for="quote in sortedQuotes" :key="quote._id">
        <span>Rating: {{ quote.rating }}</span>
        <blockquote>
          <p>{{ quote.content }}</p>
          <cite>- {{ quote.author }}</cite>
        </blockquote>
      </li>
    </ul>
  </div>
</template>

<script setup>
import { ref, onMounted, computed } from 'vue';

const quotes = ref([]);

const fetchQuotes = async () => {
  const response = await fetch('https://api.quotable.io/quotes/random?limit=5');
  const data = await response.json();
  quotes.value = data.map((quote) => ({
    ...quote,
    rating: Math.floor(Math.random() * 20) + 1,
  }));
};

onMounted(() => {
  fetchQuotes();
});

const sortOrder = ref('desc');

const sortQuotes = () => {
  if (sortOrder.value === 'desc') {
    sortOrder.value = 'asc';
  } else {
    sortOrder.value = 'desc';
  }
};

const sortedQuotes = computed(() => {
  const quotesCopy = [...quotes.value];

  if (sortOrder.value === 'desc') {
    return quotesCopy.sort((a, b) => b.rating - a.rating);
  } else {
    return quotesCopy.sort((a, b) => a.rating - b.rating);
  }
});
</script>

Inside the template, we render our list by looping through the sortedQuotes computed property to display the quotes in the desired order.

Conclusion

By leveraging Vue.js 3's computed properties, we’ve successfully implemented dynamic quote sorting functionality in the application. This empowers users to explore the quotes by rating, enhancing their overall experience. Remember, computed properties are a versatile tool for various scenarios beyond sorting. They can be used to filter data, format strings, and perform many other calculations based on your reactive data.

For a deeper dive into Vue.js 3's Composition API and computed properties, check out the fantastic free course "Vue.js Fundamentals with the Composition API". This course will equip you with the knowledge to master these concepts and become a Vue.js pro!

Feel free to have a look at the complete implementation code here.

Related Courses

Start learning Vue.js for free

Mostafa Said
Mostafa Said
With over 7 years of e-learning expertise honed at major companies like Vodafone Intelligent Solutions (_VOIS), Mostafa is full-time instructor at Vue School and a full-stack developer in the wild. He built and maintained dozens of apps using Vue, Nuxt, Laravel, Tailwind, and more. He merges modern teaching methods with coding education to empower aspiring developers of all experience levels. When he's not glued to the code editor, hackathons fuel his competitive spirit, with Deepgram and Appwrite grand prizes under his belt.

Comments

Latest Vue School Articles

Why Vue.js is a Great Starting Point for New Coders

Why Vue.js is a Great Starting Point for New Coders

Dive into Vue.js as a beginner with our comprehensive guide. Learn why Vue is perfect for starting your web development journey, with insights into its community, learning resources, and real-world uses.
Eleftheria Batsou
Eleftheria Batsou
The Vue Form Component Pattern: Robust Forms Without the Fuss

The Vue Form Component Pattern: Robust Forms Without the Fuss

Learn to create easy to use Vue forms without a library and take advantage of native HTML validation.
Daniel Kelly
Daniel Kelly

Our goal is to be the number one source of Vue.js knowledge for all skill levels. We offer the knowledge of our industry leaders through awesome video courses for a ridiculously low price.

More than 200.000 users have already joined us. You are welcome too!

Follow us on Social

© All rights reserved. Made with ❤️ by BitterBrains, Inc.