I've been struggling with this issue for a while now while working on a Vue site. I have not been able to find a solution for my specific bug in other discussions.
The concept should be straightforward - I want to have a switch that toggles a value between 'light' and 'dark', and then bind the class to that value.
<template>
<div id="app" :class='themeValue'>
<!-- Switch component from Buefy UI !-->
<b-switch size='is-large' type='is-dark' v-model='theme'></b-switch>
<!-- Other components !-->
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
theme: localStorage.getItem('theme') || false
}
},
watch: {
theme: function() {
localStorage.setItem('theme', this.theme)
}
},
computed: {
themeValue: function() {
return this.theme ? 'light' : 'dark'
}
}
}
</script>
<style lang="scss">
@import './_variables.scss';
.dark {
color: $light;
background-color: $background;
}
.light {
color: $dark;
background-color: $lightbackground;
}
</style>
I have experimented with many variations of the code, such as using `mounted()` to set `this.theme`, using an external component with `$emit`, and more.
The expected result is to default to the dark theme unless a value for 'theme' is stored in localStorage, in which case it should default to that value. The switch component should always reflect the state of the theme (i.e. if saved to light theme, the switch should default to `true`).
However, the current behavior of the code is to always default to the light theme, and the switch defaults to `false`. This leads to inconsistency where the light theme is applied when `theme === true`. The first switch press does not change the theme but does change itself to `true`, and subsequent presses work correctly (`true` applies `.light` class, `false` applies `.dark` class).
EDIT: I realized that localStorage was storing the true/false values as strings. Although, a refined implementation using JSON.parse could have worked, I opted for a `mounted` method with `if (localStorage.getItem('theme') === 'true')` which resolved the issue. It's frustrating that it took me 4 hours to figure this out.