Skip to content
Advertisement

Toggle active state on button in v-for loop using Vue 3

I’m making a filter header in Vue 3 where you select one category to view at once, so you can click to toggle on and off that filter and also if you click another, it deselects the previous active one, only one or none ever active at once.

I’ve found examples such as this jsfiddle which 1. doesn’t have a toggleable button (click again to deselect) and 2. doesn’t use a v-for loop. I am fairly confident I can transfer it to a v-for loop, but I do not know how to go about the toggling + one active at a time aspect easily.

Here’s my base code:

<button
  v-for="category in contentCategories"
  @click=""
  class="filter-button"
>
  {{ category }}
</button>
const contentCategories = ["category 1", "category 2", "category 3"];

let list = contentStore.resources;
const activeCategory = "";
const filteredList = list
  .filter((e) => e.category === activeCategory)
  .map((e) => {
    return e;
});

The behavior that I think I need is storing the active category in the activeCategory string, and applying the active tag to the corresponding button, and then be able to remove that activeCategory if the active button is clicked again OR change the activeCategory if a different button is clicked.

Apologies if this is an easy solution, I’m very new to Vue. Thank you!

Advertisement

Answer

Using composition API

Simple solution using additional ref for tracking

const selectedCategory = ref("")
const contentCategories = ref(["category 1", "category 2", "category 3"]);

<button
  v-for="category in contentCategories"
  @click="handleClick(category)"
  :class="selectedCategory === category ? 'active' : 'inactive'"
  :key="category"
>
  {{ category }}
</button>

handleClick(category) {
   selectedCategory.value = category
|

Tracking category activity if you want to have ability for multiple selections

const contentCategories = ref([
  {
    name: "Category 1",
    active: false
  },
  ...
]);

<button
  v-for="category in contentCategories"
  @click="handleClick(category)"
  :class="category.active ? 'active' : 'inactive'"
  :key="category"
>
  {{ category }}
</button>

handleClick(category) {
   find category and then set active = !active, turn off others
|
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement