javascript - Vue - 当 vuex 存储中的值更改时删除侦听器
问题描述
Automatic - 从 OS 获取设置
Light - 应用浅色主题覆盖 OS 设置
Dark - 应用深色主题覆盖 OS 设置
出了什么问题
目前,当我切换到“浅色”或“深色”,然后开始在我的 Windows 设置中更改首选配色方案时,它仍然会不断切换到我在那里选择的任何颜色。当设置不是自动的时,应该忽略它。
我认为正在发生的事情
我猜它eventListener
仍然存在,并且应该在用户选择“浅色”或“深色”时被销毁。我尝试使用 aAbortController()
但没有成功。
app.vue
在我的 app.vue 中,我查看当前设置,如果它是“自动”的,我会设置一个初始主题并EventListener
从操作系统中获取更改。
created() {
this.$store.watch(
(state) => {
return state.settings.colorSettings.automatic;
},
(currentAutomaticValue) => {
if (currentAutomaticValue) { //if automatic is true
if (
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches
) {
document
.getElementsByTagName("html")[0]
.setAttribute("theme", "theme-dark");
} else {
document
.getElementsByTagName("html")[0]
.setAttribute("theme", "theme-default");
}
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (e) => {
const darkMode = e.matches ? true : false;
document
.getElementsByTagName("html")[0]
.setAttribute(
"theme",
darkMode ? "theme-dark" : "theme-default"
);
});
}
},
{ immediate: true }
);
switchComponent.vue
在这里,当所选值更改时,我运行一个函数。这个函数看起来像这样:
methods: {
onSwitch(event) {
if (!this.colorSettings?.loading) {
switch (event.target.id) {
case "automatic":
this.colorSettings.automatic = true;
break;
case "light":
this.colorSettings.darkMode = false;
this.colorSettings.automatic = false;
break;
case "dark":
this.colorSettings.darkMode = true;
this.colorSettings.automatic = false;
break;
}
this.$store.dispatch("setDarkMode", this.colorSettings);
document
.getElementsByTagName("html")[0]
.setAttribute(
"theme",
this.colorSettings.darkMode ? "theme-dark" : "theme-default"
);
}
},
}
Settings.js 状态
import { SettingsService } from "@/api/settingsService";
const state = {
colorSettings: {
loading: false,
automatic: true,
darkMode: false,
colors: {}
}
};
const getters = {
loadingColorSettings: state => {
return state.colorSettings.loading;
},
colorSettings: state => {
return state.colorSettings;
}
};
const mutations = {
SET_COLOR_SETTINGS(state, colorSettings) {
state.colorSettings.automatic = colorSettings.automatic;
state.colorSettings.darkMode = colorSettings.darkMode;
state.colorSettings.colors = colorSettings.entityTypeColors;
},
SET_LOADING_COLOR_SETTINGS(state, isLoading) {
state.colorSettings.loading = isLoading;
}
};
const actions = {
setDarkMode: (context, updatedDarkmode) => {
context.commit("SET_LOADING_COLOR_SETTINGS", true);
SettingsService.setColoring(updatedDarkmode)
.then(response => {
context.commit("SET_COLOR_SETTINGS", response.data);
})
.catch(resp => {
console.error(resp);
})
.finally(() => {
context.commit("SET_LOADING_COLOR_SETTINGS", false);
});
}
};
export ...
任何人都可以向我推动正确的方向吗?
解决方案
EventListener
因此,毕竟删除显然是有效的。我之前尝试过这样做,但当时没有让它工作。
代码需要优化(非常欢迎提出建议!),代码看起来很乱。但这是一个开始。
我做了什么:
为侦听器制作了一个单独的功能
setTheme()
,以便我可以将其删除必须
window.matchMedia("(prefers-color-scheme: dark)")
输入一个常数,这也是能够删除它的必要条件当观察者认为
currentAutomaticValue
是假的时移除监听者methods: { setTheme(e) { const darkMode = e.matches ? true : false; document .getElementsByTagName("html")[0] .setAttribute( "theme", darkMode ? "theme-dark" : "theme-default" ); } }, created() { const media = window.matchMedia("(prefers-color-scheme: dark)"); this.$store.watch( (state) => { return state.settings.colorSettings.automatic; }, (currentAutomaticValue) => { if (currentAutomaticValue) { if ( window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ) { document .getElementsByTagName("html")[0] .setAttribute("theme", "theme-dark"); } else { document .getElementsByTagName("html")[0] .setAttribute("theme", "theme-default"); } media.addEventListener("change", this.setTheme); } else { media.removeEventListener("change", this.setTheme); if (this.colorSettings.darkMode) { document .getElementsByTagName("html")[0] .setAttribute("theme", "theme-dark"); } else { document .getElementsByTagName("html")[0] .setAttribute("theme", "theme-default"); } } }, { immediate: true } ); }
推荐阅读
- azure - 为有问题的 azure 数据块添加密钥保管库范围
- python - Keras 中的模型评估
- android - 以编程方式添加到 TableLayout 的 TextView 与父级的宽度不匹配
- google-chrome - 合并或使用实例和原生渲染与 Chrome 加集成显卡没有区别
- ionic-framework - 我们如何将值绑定到
- java - Mockito 模拟具有无关静态方法的类
- python - 如何在 jupyter 中从 github 加载整个目录并在其中运行所有 .py 文件?
- sql - sql检查范围之间是否存在范围
- python - Odoo12:strptime 无法识别格式 %p (PM/AM)?
- go - 应用程序设计:中央缓存与私有缓存