I'm recently trying to learn Vue 3 with the script setup syntax.
I am dividing some content into four tabs and wish to apply the 'active' class when one is clicked. The string value itself is updating when a tab is clicked, but I cannot seem to get the computed class property to also apply.
My template:
<div
@click="onTabClick('first')"
:class="activeState('first')"
>
<span>First</span>
</div>
<!-- repeated for second, third, and fourth... -->
My script setup:
<script lang="ts" setup>
import { computed } from "vue";
let selectedTab = "";
const activeState = computed(
() => (tab: string) => selectedTab === tab ? "active" : "inactive",
);
const onTabClick = (tab: string) => {
selectedTab = tab;
};
</script>
I am thinking I have to use ref somehow to make it reactive, but I haven't been able to find a solution for this setup. Hopefully someone here might know. Is there a way to do it like this or will I have to declare a ref(false) for each tab?
Passing parameters to computed properties should generally be avoided in favor of just using normal methods. See longer explanation here
As a method:
const activeState = (tab: string) => selectedTab === tab ? "active" : "inactive";
Another problem with your code however is the fact that the DOM won't update since no reactive variables are being updated. It's easily fixable by making selectedTab
into a ref. As a ref, values are assigned to it's .value
property.
const selectedTab = ref("");
const activeState = (tab: string) => selectedTab.value === tab ? "active" : "inactive";
const onTabClick = (tab: string) => {
selectedTab.value = tab;
};