在加载时切换 Vue3 主题/CSS 文件并单击
Switch Vue3 theme / CSS file on load and click
包含主题的推荐方法是在应用根目录下的 main.js
文件中导入:
import 'primevue/resources/themes/arya-orange/theme.css';
但我正在寻找一种方法来根据用户系统主题和用户选择来切换 CSS 文件,所以我将其移到了我的主 App.vue
:
export default {
name: "App",
components: {
HelloWorld,
toDo,
},
mounted() {
//window.matchMedia('(prefers-color-scheme: dark)').matches ? do dark : do light
},
};
<style>
@media (prefers-color-scheme: dark) {
@import url("primevue/resources/themes/bootstrap4-dark-blue/theme.css");
}
@media (prefers-color-scheme: light) {
@import url("primevue/resources/themes/bootstrap4-light-blue/theme.css");
}
</style>
我无法在 mounted 和 styles 标签中导入任何内容我也无法在 media 中导入,这两种用法都不正确。
我在网上找不到任何其他方法或指导来解决这个问题。所有解决方案都基于范围组件,使用 类 等
我可以将所有规则包装在一个主题中以
@media (prefers-color-scheme: dark) {
还有一个用于照明。但是话又说回来,我怎样才能打开用户选择?
编辑:
我找到了一种让它在负载下工作的方法:
(async () => {
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
await import('primevue/resources/themes/bootstrap4-dark-blue/theme.css');
}else {
await import('primevue/resources/themes/bootstrap4-light-blue/theme.css');
}
})();
并在点击时覆盖第一次导入:
methods: {
theme() {
(async () => {
await import("primevue/resources/themes/bootstrap4-light-blue/theme.css");
})();
},
},
但是 当我尝试使用单击将其切换回来时它什么也没做,我的猜测是因为如果系统是黑暗的,它会在第一次导入时加载黑暗主题,然后再导入点击它加载浅色主题,但之后它不会在点击时切换回深色,我的猜测是因为深色已经准备好加载并且它不会在切换时生效。
请指教
一种解决方案是像在 PrimeVue 网站上那样实施。总之,css 主题是使用 index.html 文件中的 link 导入的:
<!DOCTYPE html>
<html lang="en">
<head>
...
<link id="theme-link" rel="stylesheet" href="<%= BASE_URL %>themes/saga-blue/theme.css">
</head>
<body>
...
</body>
</html>
有关示例,请参阅 this link。
然后要切换主题,可以这样实现:
changeTheme(event) {
let themeElement = document.getElementById('theme-link');
themeElement.setAttribute('href', themeElement.getAttribute('href').replace(this.theme, event.theme));
this.theme = event.theme;
this.activeMenuIndex = null;
EventBus.emit('change-theme', event);
this.$appState.darkTheme = event.dark;
if (event.theme.startsWith('md')) {
this.$primevue.config.ripple = true;
}
localStorage.setItem('theme', this.theme);
}
这是 PrimeVue 文档中的实现方式。参见 here
包含主题的推荐方法是在应用根目录下的 main.js
文件中导入:
import 'primevue/resources/themes/arya-orange/theme.css';
但我正在寻找一种方法来根据用户系统主题和用户选择来切换 CSS 文件,所以我将其移到了我的主 App.vue
:
export default {
name: "App",
components: {
HelloWorld,
toDo,
},
mounted() {
//window.matchMedia('(prefers-color-scheme: dark)').matches ? do dark : do light
},
};
<style>
@media (prefers-color-scheme: dark) {
@import url("primevue/resources/themes/bootstrap4-dark-blue/theme.css");
}
@media (prefers-color-scheme: light) {
@import url("primevue/resources/themes/bootstrap4-light-blue/theme.css");
}
</style>
我无法在 mounted 和 styles 标签中导入任何内容我也无法在 media 中导入,这两种用法都不正确。
我在网上找不到任何其他方法或指导来解决这个问题。所有解决方案都基于范围组件,使用 类 等
我可以将所有规则包装在一个主题中以
@media (prefers-color-scheme: dark) {
还有一个用于照明。但是话又说回来,我怎样才能打开用户选择?
编辑:
我找到了一种让它在负载下工作的方法:
(async () => {
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
await import('primevue/resources/themes/bootstrap4-dark-blue/theme.css');
}else {
await import('primevue/resources/themes/bootstrap4-light-blue/theme.css');
}
})();
并在点击时覆盖第一次导入:
methods: {
theme() {
(async () => {
await import("primevue/resources/themes/bootstrap4-light-blue/theme.css");
})();
},
},
但是 当我尝试使用单击将其切换回来时它什么也没做,我的猜测是因为如果系统是黑暗的,它会在第一次导入时加载黑暗主题,然后再导入点击它加载浅色主题,但之后它不会在点击时切换回深色,我的猜测是因为深色已经准备好加载并且它不会在切换时生效。
请指教
一种解决方案是像在 PrimeVue 网站上那样实施。总之,css 主题是使用 index.html 文件中的 link 导入的:
<!DOCTYPE html>
<html lang="en">
<head>
...
<link id="theme-link" rel="stylesheet" href="<%= BASE_URL %>themes/saga-blue/theme.css">
</head>
<body>
...
</body>
</html>
有关示例,请参阅 this link。
然后要切换主题,可以这样实现:
changeTheme(event) {
let themeElement = document.getElementById('theme-link');
themeElement.setAttribute('href', themeElement.getAttribute('href').replace(this.theme, event.theme));
this.theme = event.theme;
this.activeMenuIndex = null;
EventBus.emit('change-theme', event);
this.$appState.darkTheme = event.dark;
if (event.theme.startsWith('md')) {
this.$primevue.config.ripple = true;
}
localStorage.setItem('theme', this.theme);
}
这是 PrimeVue 文档中的实现方式。参见 here