3
votes

I'm using Nuxt.js v2.12.2 with Vuetify. I installed Vuetify during the initial configuration of the new project.

I want to build a static website with some functionality like change the theme from dark to light.

So I added a switch in my default layout to change this property: $vuetify.theme.dark

Here's my code for the switch:

<v-switch v-model="$vuetify.theme.dark" />

I even tried in this way but is the same:

<v-switch @click="$vuetify.theme.dark = !$vuetify.theme.dark" />

When I click on the switch the property change correcly. But if I change page or I reload, it goes back to his previous value.

How do I change this property so that it stays that way for the session? Do I need to save it somewhere?

Here's the code inside nuxt.config.js:

 vuetify: {
customVariables: ['~/assets/variables.scss'],
theme: {
  themes: {
    dark: {
      primary: colors.blue.darken2,
      accent: colors.grey.darken3,
      secondary: colors.amber.darken3,
      info: colors.teal.lighten1,
      warning: colors.amber.base,
      error: colors.deepOrange.accent4,
      success: colors.green.accent3
    },
    light: {
      primary: '#3f51b5',
      secondary: '#b0bec5',
      accent: '#8c9eff',
      error: '#b71c1c',
    },
  }
}

Thanks for the help.

4

4 Answers

4
votes

As Suggested by Art Mary, one additional thing you need to do is store the setting in Localstorage and then on the application load, fetch the setting from there. So basically:

  1. Watch for the goDark property.
  2. On change of goDark property store the value in Localstorage.
  3. In the component containing v-app, on mounted (onMounted) fetch the value from there localStorage.getItem('[your key for dark property]'), if there is any, use it or assign default.
3
votes

First of all in Vuetify config file you need to add this property:

dark: true/false

the configuration should now look like this:

theme: {
  dark: true,
  themes: {
    dark: {
      primary: colors.blue.darken2,
      accent: colors.grey.darken3,
      secondary: colors.amber.darken3,
      background: '#34358e'
    },
    light: {
     primary: '#3f51b5',
     secondary: '#b0bec5',
     accent: '#8c9eff',
     error: '#b71c1c',
    }
  }
}

Then in your Layout in the v-app component you have to bind a method

it look like this:

<v-app :dark="setTheme">
 <v-container>
  <v-switch v-model="goDark"></v-switch>
 </v-container>
</v-app>

and in your script tag add goDark in data and setTheme as a computed property.

<script>
export default {
  data: () => ({
    goDark: false,
  }),
  computed: {
    setTheme() {
      if (this.goDark === true) {
        return (this.$vuetify.theme.dark = true);
      } else {
        return (this.$vuetify.theme.dark = false);
      }
    }
  }
};
</script>

It should work now.

2
votes

I fixed it the way below.

1. Set switcher

layouts/default.vue

<template>
  <div>
    <v-btn
      class="px-1"
      min-width="0px"
      icon
      :color="$vuetify.theme.dark ? 'yellow' : 'indigo'"
      @click="switchTheme()"
    >
      <v-icon>mdi-theme-light-dark</v-icon>
    </v-btn>
  </div>
</template>
<script>
export default {
  mounted() {
    this.$vuetify.theme.dark = this.$store.state.darkMode
  },
  methods: {
    switchTheme() {
      this.$store.commit('SWITCH_DARK')
      this.$vuetify.theme.dark = this.$store.state.darkMode
    },
  }
}
</script>

2. Save dark mode state in Vuex store

store/index.js

export const state = () => ({
  darkMode: false,
})

export const mutations = {
  SWITCH_DARK(state) {
    state.darkMode = !state.darkMode
  },
}

3. Make store persistent at page update

Install vuex-persist:

npm install --save vuex-persist
1
votes

This works for me for retrieving dark mode after app reload:

mounted() {
    setTimeout(() => {
      this.$vuetify.theme.dark = localStorage.getItem('dark') === 'true'
    }, 200)
}

For switching theme in runtime:

computed: {
   mode: {
    set(theme) {
       this.$vuetify.theme.dark = theme === 'dark'
       localStorage.setItem('dark', theme === 'dark')
     },
    get() {
       return this.$vuetify.theme.dark ? 'dark' : 'light'
    }
   }
 }