简体   繁体   中英

vuex state and getters are updated, but computed value doesn't react

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.

Looks like you are using two different instances of Vue. In main.js you are importing vue but in src/store/index.js you are importing vue/dist/vue.common.js and telling each one to use Vuex. Try using vue for both imports.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM