这个问题让我在开发Vue站点时迷惑了一段时间,而且我还不能用其他线程解决我的特定bug。这个想法应该很简单,有一个在“light”和“dark”之间切换的开关,并将类绑定到该值。
<template>
<div id="app" :class='themeValue'>
<!-- Switch component from Buefy UI !-->
<b-switch size='is-large' type='is-dark' v-model='theme'></b-switch>
<!-- Other components !-->
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
theme: localStorage.getItem('theme') || false
}
},
watch: {
theme: function() {
localStorage.setItem('theme', this.theme)
}
},
computed: {
themeValue: function() {
return this.theme ? 'light' : 'dark'
}
}
}
</script>
<style lang="scss">
@import './_variables.scss';
.dark {
color: $light;
background-color: $background;
}
.light {
color: $dark;
background-color: $lightbackground;
}
</style>
我尝试了上面的一百万种不同的变体,包括使用mounted()
设置this.theme
,将所有逻辑保存在外部组件中,以及使用$emit
等。
预期的行为是默认为深色主题,除非localStorage拥有' theme‘的值,在这种情况下将默认为深色主题。开关组件应始终与主题的状态匹配(即,如果保存为轻主题,则开关应默认为true
)。
上述代码的行为总是默认为light主题,而开关的默认设置为false。这两者不同步(当theme === true
时应用轻主题),第一次按下开关不会更改主题,但会将自身更改为true
,并且后续按键可以正常工作(true
应用.light
类,false
应用.dark
)
编辑: localStorage将true/false值存储为字符串。我认为你可以用JSON.parse做一个很好的实现,但我最终只用了一个带有if (localStorage.getItem('theme') === 'true')
的mounted
,它工作得很好。不用说,我真的对自己很生气,因为我花了4个小时。
发布于 2021-08-31 17:05:44
好的,这就是我是如何让它在本地工作的,我改变了or语句,并将属性名改为主题。
<template>
<div id="app" :class='themeValue'>
<!-- Switch component from Buefy UI !-->
<button size='is-large' type='is-dark' @click='themes = !themes'>klik</button>
<!-- Other components !-->
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
themes: false || localStorage.getItem('theme')
}
},
watch: {
theme: function() {
localStorage.setItem('theme', this.theme)
}
},
computed: {
themeValue: function() {
return this.themes ? 'light' : 'dark'
}
}
}
</script>
<style lang="scss">
.dark {
color: white;
background-color: black;
}
.light {
color: black;
background-color: white;
}
</style>
因此,我建议您将监视函数的名称更改为类似于updateTheme的名称,并切换data属性中的条件语句,这样它就可以工作了:)
https://stackoverflow.com/questions/69002473
复制相似问题