A Filtered Menu

In Conditions and Lists, you filtered the menu with a function that the template called. A computed value can do that job too: it can hold a whole list, worked out from other data. Here's a menu that shows only what costs at most as much as the customer wants to pay:

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

const menu = [
    { id: 1, name: "Espresso", price: 2 },
    { id: 5, name: "Carrot Cake", price: 4 },
    { id: 6, name: "Cheesecake", price: 5 },
];
const maxPrice = ref(4);

const affordable = computed(() => {
    return menu.filter((item) => item.price <= maxPrice.value);
});
</script>

<template>
    <input v-model.number="maxPrice" type="number">
    <ul>
        <li v-for="item in affordable" :key="item.id">{{ item.name }}</li>
    </ul>
</template>

v-for goes through affordable as through any array. At first, the list shows the espresso and the carrot cake. When the customer types 2, Vue filters again, because maxPrice, which the function reads, has changed, and the list shows only the espresso. filter() makes a new array, so menu itself stays as it is.

Notice that menu has no .value. It's a plain array, not a ref, because it never changes. Only refs and computed values have .value.

In this exercise, the customer chooses a category with a select and searches by name. v-model already puts what they choose and type into category and search, but the list still shows the whole menu. One computed value can read both refs, and Vue works it out again when either of them changes.

A tip for the search: includes() tells you whether a text contains another one, but for it, "Tea" and "tea" are different texts. Turn both into lowercase first, with toLowerCase().

Instructions

  1. Create a computed value shownMenu with the items of the chosen category, or the whole menu when it's "all". Show shownMenu in the list instead of menu, and try the select.

  2. Make the search work too: shownMenu has only the items whose name contains the text in search, whatever the capitals. The category still applies: the category Cake and the search carrot show only the carrot cake.