I'm currently trying to implement a simple theme-switching function in which the active theme is saved in a vuex store state. Upon pressing a button the theme is supposed to switch.
Here is a video with vue-devtools, demonstrating the problem
As you can see in the video the data is successfully changed in the state and the getter returns the correct value, however the computed value of my component doesn't react to the change.
/src/main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
import Vuex from 'vuex'
import Icon from 'vue-awesome/components/Icon'
Vue.use(Vuex)
Vue.component('icon', Icon)
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
/src/App.vue
<template>
<div id="app"
:class="themeName">
<div id="themeSwitch"
v-on:click="switchTheme">
<icon name="lightbulb"
:class="themeName"></icon>
</div>
<router-view/>
</div>
</template>
<script>
import "vue-awesome/icons/lightbulb"
import { mapState, mapGetters } from "vuex"
var app = {
name: "App",
beforeCreate() {
this.$store.dispatch("LOAD_THEME")
},
computed: {
themeName() {
return this.$store.getters.GET_THEME
}
},
methods: {
switchTheme: function(event) {
this.$store.dispatch("SWITCH_THEME")
}
}
};
export default app;
</script>
/src/store/index.js
import Vue from "vue/dist/vue.common.js"
import Vuex from "vuex/dist/vuex.js"
import * as Cookies from "tiny-cookie"
Vue.use(Vuex);
const themes = ["dark", "light"];
const store = new Vuex.Store({
state: {
themeName: ''
},
actions: {
LOAD_THEME({ commit, state }) {
if (state.themeName.length > 0) return
var themeId = Cookies.getCookie("themeId")
if (!themeId) commit("SET_COOKIE", themeId = 1)
commit("SET_THEME", themeId)
},
SWITCH_THEME({ commit, state }){
var id = themes.indexOf(state.themeName) < 1 ? 1 : 0
commit("SET_THEME", id)
commit("SET_COOKIE", id)
}
},
getters: {
GET_THEME: state => {
return state.themeName
}
},
mutations: {
SET_COOKIE: (state, id) => {
Cookies.setCookie("themeId", id, { expires: "1M" })
},
SET_THEME: (state, id) => {
state.themeName = themes[id]
}
}
});
export default store;
I tried a few different approaches for the computed property, which I found all over the internet. But none of them made any difference.
computed: mapState({
themeName: state => state.themeName
})
computed: {
...mapGetters({
themeName: 'GET_THEME'
})
}
If I use data instead of computed and I manually set the string it works, but that defeats the purpose of the state if I have to manually set every local variable in every component.
Any help would be appreciated.
this.$store.state.themeName
– Eric Guan