lidian manoha.
lidian manoha.

Reputation: 99

how to refresh the value of computed when it changes

I want to change the value of: class = "theme - $ {nightMode}" when I click toggle but it only works if I refresh the page and I can't figure out how to set up a watcher so that 'he looks at the value modify

<template>
  <div id="app" :class="`theme-${nightMode}`">
    <router-view />
    <Header />
    <Footer />
  </div>
</template>

<script>
import Header from '@/components/molecules/Header/index.vue';
import Footer from '@/components/molecules/Footer/index.vue';

export default {
  name: 'App',

  components: { Header, Footer },
  data() {
    return {
      themeMode: ''
    };
  },

  computed: {
    nightMode() {
      const mode = localStorage.getItem('DarkMode');
      if (mode === 'true') {
        console.log('dark');
        return 'dark';
      } else {
        console.log('light');
        return 'light';
      }
    }
  },
  watch: {
    themeMode(newVal) {
      this.nightMode = newVal;
    }
  }
};
</script>

<style lang="scss" src="./assets/scss/style.scss"></style>

Upvotes: 0

Views: 2233

Answers (2)

Amaarockz
Amaarockz

Reputation: 4684

Below are the changes

       <template>
         <div id="app" :class="`theme-${themeMode}`">
           <router-view />
           <Header />
           <Footer />
         </div>
       </template>
       
       <script>
       import { mapGetters } from 'vuex'; // change Added
       import Header from '@/components/molecules/Header/index.vue';
       import Footer from '@/components/molecules/Footer/index.vue';
       
       export default {
         name: 'App',
       
         components: { Header, Footer },
         data() {
           return {
             themeMode: 'light' // change Added
           };
         },
         computed: {
           ...mapGetters(['isDark']) // change Added
         },
         watch: { // change Added
           isDark(newVal) {
            this.themeMode = newVal ? 'dark' : 'light';
          }
         },
         mounted() {
           const mode = localStorage.getItem('DarkMode');
           if (mode === 'true') {
               console.log('dark');
               return 'dark';
             } else {
               console.log('light');
               return 'light';
           }
         }
       };
       </script>
       
       <style lang="scss" src="./assets/scss/style.scss"></style>
       ```

Upvotes: 1

David ROSEY
David ROSEY

Reputation: 1805

You can't updating computed value by doing things like this.nightMode = newVal;. Even if this is possible (I guess no) this would be missusing the vue framwork.

I think that it would be better to init themeMode inside the mounted (or created) hook see below:

<template>
  <div id="app" :class="appClass">
    <router-view />
    <Header />
    <Footer />
  </div>
</template>

<script>
import Header from '@/components/molecules/Header/index.vue';
import Footer from '@/components/molecules/Footer/index.vue';

export default {
  name: 'App',

  components: { Header, Footer },
  data() {
    return {
      themeMode: '',
    };
  },
  mounted() {
    const mode = localStorage.getItem('DarkMode');
    this.themeMode = mode === 'true' ? 'dark' : 'light';
  },
  computed: {
    appClass() {
      return `theme-${this.themeMode}`;
    },
  },
};
</script>

EDIT:

Actually your toogle define in Home component is not modifying your local data themeMode, instead, it modify the isDark state of your vuex store. => You should directly use the isDark state to set you class:

<template>
  <div id="app" :class="appClass">
    <router-view />
    <Header />
    <Footer />
  </div>
</template>

<script>
import Header from '@/components/molecules/Header/index.vue';
import Footer from '@/components/molecules/Footer/index.vue';

export default {
  name: 'App',

  components: { Header, Footer },
  mounted() {
    this.$store.commit('initializeDarkMode', localStorage.getItem('DarkMode'));
  },
  computed: {
    appClass() {
      return `theme-${this.$store.state.isDark === 'true' ? 'dark' : 'light'}`;
    },
  },
};
</script>

Upvotes: 0

Related Questions