带有 vuex 的暗模式并保存在本地存储中 [英] darkmode with vuex and save in localstorage

查看:29
本文介绍了带有 vuex 的暗模式并保存在本地存储中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 chrome 错误,告诉我写操作失败:计算属性isDark"是只读的.

我的突变在 locastorage 中创建了一个 DarkMode 键,我还创建了一个存储来检查本地存储中是否存在 DarkMode

它可以工作,但是如果我刷新页面,则突变会反转,例如,如果在 localestorage 中,darkMode 为 true,如果我单击切换按钮,则突变也是 true,那么应该返回 false

我的页面

 

<div class="toggleTheme"><ToggleBtnThemelabelOn=暗"labelOff=光"v-model:value=isDark"@input=模式"/>

<div class="title"><h1 :class="isDark ?'dark' : 'light'">Lidian Manoha</h1>

</模板><脚本>从 'vuex' 导入 { mapMutations, mapGetters };从@/components/atoms/ToggleBtn/index"导入 ToggleBtnTheme;导出默认{name: '家',成分: {ToggleBtn主题},方法: {...mapMutations('themeDarkMode', ['toggleDarkMode']),模式() {this.toggleDarkMode();}},计算:{...mapGetters('themeDarkMode', ['isDark'])},手表: {}};<style lang="scss";src="./style.scss";作用域></style>```我的店铺```返回{暗模式:真,isDark: 假};},吸气剂:暗模式吸气剂,突变:DarkModeMutations,动作:DarkModeAction};``我的 getters.js``导出默认{isDark:状态 =>state.isDark};``我的mutations.js``导出默认{切换暗模式:状态 =>{state.isDark = !state.isDark;console.log('mutation', state.isDark);localStorage.setItem('DarkMode', JSON.stringify(state.isDark));}};```还有我的 ToggleBtn```<模板><div id="toggleBtn"><div class="toggleBtnContainer"><标签类=标签"v-if=label">{{label }}<div class="containerToggle"><输入v-bind="$attrs";:id="`toggle${uuid}`";:disabled="禁用";类型=复选框":checked="value ||检查"@change=$emit('update:value', $event.target.checked)";/><标签:for="`toggle${uuid}`";v-html=值?labelOn : labelOff"@click="$emit('click', $event)";></标签>

</模板><脚本>从'vue-uuid'导入{uuid};导出默认{name: 'toggleBtn',继承属性:假,道具: {value: { type: [Boolean, String, Number, Function], 默认: false },检查:{ 类型:布尔值,默认值:假},labelOn:{ 类型:字符串,默认值:'关闭'},labelOff: { 类型:字符串,默认值:'on' },标签:{ 类型:字符串,默认值:空},禁用:{ 类型:布尔值,默认值:false }},数据() {返回 {uuid: uuid.v4()};}};<style lang="scss";src="./style.scss";作用域></style>```

解决方案

那可能是因为你错过了一个点.当您刷新页面时...即应用程序重新加载...如果您发现本地存储中有可用的数据('Darkmode'),那么您首先需要通过更改来设置它.通过这样做,当您刷新页面时会发生什么……如果darkmode 已经设置为true,那么您的vuex state('isDark') 也将设置为true.因此,当您点击它时,它将按预期切换.

最好有两个突变以避免混淆

我的mutations.js导出默认{切换暗模式:状态 =>{state.isDark = !state.isDark;console.log('mutation', state.isDark);localStorage.setItem('DarkMode', JSON.stringify(state.isDark));},initializeDarkMode:(状态,有效载荷)=>{state.isDark = 有效载荷;//有效载荷实际上是存储在本地存储中的值}};

当应用加载时,只需调用第二个突变以使用本地存储值初始化状态.

 this.initializeDarkMode(DarkMode);//DarkMode 包含从本地存储中获取的值

下面我修改了代码来调用第二个突变

 

<div class="toggleTheme"><ToggleBtnThemelabelOn=暗"labelOff=光"v-model:value=isDarkMode"//****************添加了更改****************@input=模式"/>

<div class="title"><h1 :class="isDark ?'dark' : 'light'">Lidian Manoha</h1>

</模板><脚本>从 'vuex' 导入 { mapMutations, mapGetters };从 '@/components/atoms/ToggleBtn/index' 导入 ToggleBtnTheme;导出默认{name: '家',成分: {ToggleBtn主题},数据() {返回 {isDarkMode: this.isDark,},手表: {isDark(newVal) {this.isDarkMode = newVal;}},//****************下面添加了更改****************安装(){const isDark = localStorage.getItem('DarkMode');if(isDark && isDark === '真') {this.initializeDarkMode(true);this.isDarkMode = true;} 别的 {this.initializeDarkMode(false);this.isDarkMode = false;}方法: {...mapMutations('themeDarkMode', ['toggleDarkMode', 'initializeDarkMode']),模式() {this.toggleDarkMode();}},计算:{...mapGetters('themeDarkMode', ['isDark'])},手表: {}};<style lang="scss";src="./style.scss";作用域></style>

I have a chrome bug telling me Write operation failed: computed property "isDark" is readonly.

my mutation create a DarkMode key in the locastorage and I also create a store that checks if DarkMode exists in the localestorage

it works but if I refresh the page the mutation is inverted for example if in the localestorage darkMode is true if I click on the toggle the mutation is also a true then what should return false

My Page

  <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>```

解决方案

Thats probably because you missed a point. When you refresh the page...ie the app reloads... if you find that there is a data('Darkmode') available in the local storage then you need to set it through the mutation in the first place. By doing so what happens is when you refresh the page...if darkmode is already set to true then your vuex state('isDark') will also be set to true. Therefore when you click on that it will toggle as expected.

Its better to have two mutations to avoid confusions

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
      }
    };

When the app loads, just call the second mutation to initialize the state with the local storage value.

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

Below I have modified the code to call the second mutation

  <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>

这篇关于带有 vuex 的暗模式并保存在本地存储中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆