Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

CamKem's avatar
Level 10

Issue with conditionally rendering flash message from js store

Hello, I am trying to get a flash component to conditionally render from an object and functions stored inside a js store file that is imported into a View as part of a project i am doing to learn vue.

The problem I am having is that when then increment or decrement functions are called & the count number is greater than 10 or less than 0 it doesn't set the flash object to true & then render the div.

This is my CounterView.vue component, which is just a basic component to demonstrate using a external store file to hold the data & methods for the counter.

<script setup>
import { counter } from "@/stores/counterStore.js";
import { ref } from "vue";
import FlashMessage from "@/components/FlashMessage.vue";

//create a reactive object for the flash message
let flash = ref({
  show: false,
  message: "",
});

</script>

<template>
  <div>
    <h1>Counter View</h1>
    <p>
      <button @click="counter.increment()">+</button>
      {{ counter.count }}
      <button @click="counter.decrement()">-</button>
    </p>
  </div>
  <FlashMessage :flash="flash" />
</template>

Then this is is the counterStore.js file that holds the reactive counter object and related actions/methods.

import { reactive, ref } from "vue";

export let flash = ref({
  show: false,
  message: "",
});

export function showFlash(message) {
  console.log("showFlash triggered");
  flash.value.show = true;
  flash.value.message = message;
  return flash;
}

export let counter = reactive({
  // this is a reactive object (state)
  count: 0,

  // this is a reactive method/action (mutation)
  increment() {
    if (this.count >= 10) {
      showFlash("You can't increment more than 10 times");
      return;
    } else {
      showFlash("Number incremented");
    }
    this.count++;
  },

  // this is a reactive method/action (mutation)
  decrement() {
    if (this.count <= 0) {
      showFlash("You can't decrement less than 0");
      return;
    } else {
      showFlash("Number decremented");
    }
    this.count--;
  },
});

Then this is my FlashMessage.vue component where the flash message is displayed.

<template>
  <div
    v-if="props.flash.show"
    class="absolute bg-blue-500 text-white py-4 px-6 rounded-xl text-md transition duration-500 ease-in-out transform hover:opacity-75"
  >
    {{ props.flash.message }}
  </div>
</template>

<script setup>
import { watch } from "vue";

// define the props
let props = defineProps({
  flash: {
    type: Object,
    show: Boolean,
    message: String,
  },
});

// watch the value of show and if it is true, set it to false after 3 seconds
watch(
  () => props.flash.show,
  (show) => {
    if (show) {
      console.log("show is true");
      setTimeout(() => {
        props.flash.show = false;
      }, 3000);
    }
  }
);
</script>

The flash message is working perfectly if it is called directly from inside the component, by moving the showFlash function & also the counter object with the increment & decrement functions into the CounterView.vue, but I really want to work out how to get this working inside of the external store js file so that the flash message can be rended by the functions inside of the exported counter object.

Please help, I have been stuck on this one all day!

0 likes
2 replies
CamKem's avatar
Level 10

Can anyone help with this one?

CamKem's avatar
CamKem
OP
Best Answer
Level 10

Ah well I figured it out eventually, turn out I needed to remove the flash object from the View, then import flash from the store file & it works! Nice to figure things out when you have been stuck on the problem for a while!

Please or to participate in this conversation.