I’m trying to change a picture (daytime picture vs nighttime picture) dynamically when a person hits the light button. It works, but I have to refresh the page for the picture to show. Daytime and nighttime are basically just booleans of ‘true’ or ‘false’ for my theme variable.
I tried coding it this way:
useTheme.js:
import { ref, watchEffect } from 'vue';
export default function useTheme() {
const theme = ref(JSON.parse(localStorage.getItem('theme') || 'false'));
watchEffect(() => {
localStorage.setItem('theme', String(theme.value));
});
return { theme };
}
App.vue:
const { theme } = useTheme(); // Access the shared state.
const toggleTheme = () => {
theme.value = !theme.value;
document.body.classList.toggle('dark-theme', theme.value);
localStorage.setItem('theme', JSON.stringify(theme.value));
}
Home.vue (Where the problem resides):
- Part of the HTML:
<img :src="banner" alt="Daytime Banner">
- Calculating the daytime vs nighttime:
import DayTimeBanner from "@/assets/banner-city-daytime.png";
import NightTimeBanner from "@/assets/banner-city-nighttime.png";
...
const { theme } = useTheme(); // Access the same shared state.
const banner = computed(() => theme.value ? NightTimeBanner : DayTimeBanner);
Any clue on what might be going on? Changes to the theme background is reactive, but for the banner, I have to refresh the page for the image to pop up.
2
Answers
One of the reasons might be that useTheme does not return a reactive value. Try using ref or reactive
Would be the easiest if you could apply a CSS instead of an asset to src.
Predefine the two classes for both of the banners ex:,
I assume you know your way around CSS 🙂