Omitted import statements for the sake of being concise
inputData.ts
export const useInputDataStore = defineStore("inputData", {
state: () => {
return {
currentlyActiveInput: -1
}
},
actions: {
focusInput(inputId: number) {
this.currentlyActiveInput = inputId
}
}
})
InputBox.vue
<script setup lang="ts">
const store = useInputDataStore()
const props = defineProps<{
isActive: boolean,
inputId: number
}>();
const { isActive, inputId } = props;
const onClick = () => {
store.focusInput(inputId);
}
const headerTag = ref<null | HTMLElement>(null);
onMounted(() => {
if (isActive) {
headerTag.value!!.style.visibility = "visible"
} else {
headerTag.value!!.style.visibility = "hidden"
}
});
</script>
<template>
<h1 ref="headerTag">is active </h1>
<h1 @click="onClick">{{ inputId }}</h1>
</template>
ParentComponent.vue
<script setup lang="ts">
const store = useInputDataStore();
const { currentlyActiveInput } = storeToRefs(store);
</script>
<template>
<InputBox
:v-for="index in 10"
:key="index"
:is-active="index === currentlyActiveInput"
:input-id="index"
/>
</template>
Here's what it will look like (I changed the font-size without showing you):
Desired Behavior
In the image there is a little gap between the letters. That's the invisible <h1> tag that I am trying to set to visible when the number is clicked (and then have it be set back to invisible when the next number is clicked).
What's Broken?
When you click on the number, nothing updates. The value in the store is changing (at least, I think). But none of the components get re-rendered. I believe the problem has to do with me using onMounted
Also...
I am aware that there is much simpler way to do this using this code
<h1 v-if="isActive">is active </h1>
I am trying to get a deeper understanding of Vue and comprehend why my code doesn't work.