使用 vuex 的暗模式并保存在本地存储中
darkmode with vuex and save in localstorage
我有一个 chrome 错误告诉我写入操作失败:计算 属性“isDark”是只读的。
我的突变在 locastorage 中创建了一个 DarkMode 键,我还创建了一个存储来检查 localestorage 中是否存在 DarkMode
它有效,但如果我刷新页面,则突变会反转,例如,如果在本地存储中,darkMode 为真,如果我单击切换按钮,突变也为真,那么应该 return 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>```
那可能是因为你漏掉了一点。当您刷新页面时...即应用程序重新加载...如果您发现本地存储中有数据('Darkmode')可用,那么您首先需要通过突变来设置它。通过这样做,当您刷新页面时会发生什么......如果 darkmode 已经设置为 true,那么您的 vuex state('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>
我有一个 chrome 错误告诉我写入操作失败:计算 属性“isDark”是只读的。
我的突变在 locastorage 中创建了一个 DarkMode 键,我还创建了一个存储来检查 localestorage 中是否存在 DarkMode
它有效,但如果我刷新页面,则突变会反转,例如,如果在本地存储中,darkMode 为真,如果我单击切换按钮,突变也为真,那么应该 return 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>```
那可能是因为你漏掉了一点。当您刷新页面时...即应用程序重新加载...如果您发现本地存储中有数据('Darkmode')可用,那么您首先需要通过突变来设置它。通过这样做,当您刷新页面时会发生什么......如果 darkmode 已经设置为 true,那么您的 vuex state('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>