programing

vuex를 사용하여 로컬 스토리지에 저장하는 다크 모드

lovejava 2023. 6. 18. 10:00

vuex를 사용하여 로컬 스토리지에 저장하는 다크 모드

쓰기 작업 실패를 알려주는 크롬 버그가 있습니다. 계산된 속성 "isDark"는 읽기 전용입니다.

내 돌연변이는 로컬 저장소에 DarkMode 키를 생성하고 로컬 저장소에 DarkMode가 있는지 확인하는 저장소를 생성합니다.

작동하지만 페이지를 새로 고치면 변환이 반전됩니다. 예를 들어 로컬 저장소 darkMode가 true인 경우 전환을 클릭하면 변환도 true이고 이 경우 false를 반환해야 합니다.

내 페이지

  <div id="home">
    <div class="toggleTheme">
      <ToggleBtnTheme
        labelOn="Dark"
        labelOff="Light"
        v-model:value="isDark"
        @input="mode"
      />
    </div>
    <div class="title">
      <h1 :class="isDark ? 'dark' : 'light'">Lidian Manoha</h1>
    </div>
  </div>
</template>

<script>
import { mapMutations, mapGetters } from 'vuex';
import ToggleBtnTheme from '@/components/atoms/ToggleBtn/index';

export default {
  name: 'Home',
  components: {
    ToggleBtnTheme
  },

  methods: {
    ...mapMutations('themeDarkMode', ['toggleDarkMode']),
    mode() {
      this.toggleDarkMode();
    }
  },

  computed: {
    ...mapGetters('themeDarkMode', ['isDark'])
  },
  watch: {}
};
</script>

<style lang="scss" src="./style.scss" scoped></style>```

My Stores

    ```   return {
          darkMode: true,
          isDark: false
        };
      },
      getters: DarkModeGetters,
      mutations: DarkModeMutations,
      action: DarkModeAction
    };
    
    ```

My getters.js

    ```
    export default {
      isDark: state => state.isDark
    };
    ```

My mutations.js

    ```
    export default {
      toggleDarkMode: state => {
        state.isDark = !state.isDark;
        console.log('mutation', state.isDark);
        localStorage.setItem('DarkMode', JSON.stringify(state.isDark));
      }
    };```

And my ToggleBtn

    ```<template>
      <div id="toggleBtn">
        <div class="toggleBtnContainer">
          <label class="label" v-if="label">{{ label }}</label>
          <div class="containerToggle">
            <input
              v-bind="$attrs"
              :id="`toggle${uuid}`"
              :disabled="disabled"
              type="checkbox"
              :checked="value || checked"
              @change="$emit('update:value', $event.target.checked)"
            />
            <label
              :for="`toggle${uuid}`"
              v-html="value ? labelOn : labelOff"
              @click="$emit('click', $event)"
            ></label>
          </div>
        </div>
      </div>
    </template>
    
    <script>
    import { uuid } from 'vue-uuid';
    
    export default {
      name: 'toggleBtn',
      inheritAttrs: false,
      props: {
        value: { type: [Boolean, String, Number, Function], default: false },
        checked: { type: Boolean, default: false },
        labelOn: { type: String, default: 'off' },
        labelOff: { type: String, default: 'on' },
        label: { type: String, default: null },
        disabled: { type: Boolean, default: false }
      },
      data() {
        return {
          uuid: uuid.v4()
        };
      }
    };
    </script>
    
    <style lang="scss" src="./style.scss" scoped></style>```

그것은 아마도 당신이 한 점을 놓쳤기 때문일 것입니다.페이지를 새로 고칠 때...즉, 앱이 다시 로드됩니다...로컬 스토리지에 사용 가능한 데이터('다크 모드')가 있는 경우 처음에 변환을 통해 데이터를 설정해야 합니다.이렇게 하면 페이지를 새로 고칠 때 발생하는 작업입니다. 다크 모드가 이미 true로 설정되어 있으면 vuex 상태('isDark')도 true로 설정됩니다.따라서 클릭하면 예상대로 전환됩니다.

혼동을 피하기 위해 두 개의 돌연변이를 갖는 것이 더 좋습니다.

My mutations.js

   
    export default {
      toggleDarkMode: state => {
        state.isDark = !state.isDark;
        console.log('mutation', state.isDark);
        localStorage.setItem('DarkMode', JSON.stringify(state.isDark));
      },
      initializeDarkMode: (state, payload) => {
        state.isDark = payload; // payload is actually the value that was stored in the local storage
      }
    };

앱이 로드되면 두 번째 변환을 호출하여 로컬 스토리지 값으로 상태를 초기화합니다.

  this.initializeDarkMode(DarkMode);  // DarkMode contains the value fetched from local storage

아래에서 나는 두 번째 돌연변이를 부르도록 코드를 수정했습니다.

  <div id="home">
    <div class="toggleTheme">
      <ToggleBtnTheme
        labelOn="Dark"
        labelOff="Light"
        v-model:value="isDarkMode" // ****************Changes added ***************** 
        @input="mode"
      />
    </div>
    <div class="title">
      <h1 :class="isDark ? 'dark' : 'light'">Lidian Manoha</h1>
    </div>
  </div>
</template>

<script>
import { mapMutations, mapGetters } from 'vuex';
import ToggleBtnTheme from '@/components/atoms/ToggleBtn/index';

export default {
  name: 'Home',
  components: {
    ToggleBtnTheme
  },
  data() {
    return {
     isDarkMode: this.isDark,
     },
   
  watch: {
     isDark(newVal) {
       this.isDarkMode = newVal;
     }
  },
// ****************Changes added below ***************** 
  mounted() { 
   const isDark = localStorage.getItem('DarkMode');
   if(isDark && isDark === 'true') {
       this.initializeDarkMode(true); 
       this.isDarkMode = true;
    } else {
      this.initializeDarkMode(false);
      this.isDarkMode = false;
  }
  methods: {
    ...mapMutations('themeDarkMode', ['toggleDarkMode', 'initializeDarkMode']),
    mode() {
      this.toggleDarkMode();
    }
  },

  computed: {
    ...mapGetters('themeDarkMode', ['isDark'])
  },
  watch: {}
};
</script>

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

언급URL : https://stackoverflow.com/questions/65807129/darkmode-with-vuex-and-save-in-localstorage