Appearance
主题切换
跟随系统的主题切换
知识点
prefers-color-scheme
: CSS 媒体特性用于检测用户是否有将系统的主题色设置为亮色或者暗色。window.matchMedia()
: 方法返回一个新的 MediaQueryList 对象,表示指定的媒体查询 (en-US)字符串解析后的结果。返回的 MediaQueryList 可被用于判定 Document 是否匹配媒体查询,或者监控一个 document 来判定它匹配了或者停止匹配了此媒体查询。
css
@media (prefers-color-scheme: dark) { }
@media (prefers-color-scheme: light) { }
@media (prefers-color-scheme: dark) { }
@media (prefers-color-scheme: light) { }
1
2
3
2
3
示例
ts
import { watchEffect, ref } from "vue";
type Theme = "light" | "dark" | "OS";
const LOCAL_KEY = "__theme__";
const theme = ref<Theme>((localStorage.getItem(LOCAL_KEY) as Theme) || "light");
const match = matchMedia("(prefers-color-scheme: dark)");
function followOS() {
document.documentElement.dataset.theme = match.matches ? "dark" : "light";
}
watchEffect(() => {
localStorage.setItem(LOCAL_KEY, theme.value);
if (theme.value === "OS") {
followOS();
// 实现系统主题切换后 页面能自动识别
match.addEventListener("change", followOS);
} else {
document.documentElement.dataset.theme = theme.value;
match.removeEventListener("change", followOS);
}
});
export default function useTheme() {
return { theme };
}
import { watchEffect, ref } from "vue";
type Theme = "light" | "dark" | "OS";
const LOCAL_KEY = "__theme__";
const theme = ref<Theme>((localStorage.getItem(LOCAL_KEY) as Theme) || "light");
const match = matchMedia("(prefers-color-scheme: dark)");
function followOS() {
document.documentElement.dataset.theme = match.matches ? "dark" : "light";
}
watchEffect(() => {
localStorage.setItem(LOCAL_KEY, theme.value);
if (theme.value === "OS") {
followOS();
// 实现系统主题切换后 页面能自动识别
match.addEventListener("change", followOS);
} else {
document.documentElement.dataset.theme = theme.value;
match.removeEventListener("change", followOS);
}
});
export default function useTheme() {
return { theme };
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
css
/* 暗色主题 */
html[data-theme='dark'] {
--text-color: #fff;
--bg1: #102128;
--bg2: #2d5567;
}
/* 明亮主题 */
:root {
--text-color: #333;
--bg1: #c7ffdd;
--bg2: #fbd988;
}
/* @media (prefers-color-scheme: dark) { } */
/* @media (prefers-color-scheme: light) {} */
/* 暗色主题 */
html[data-theme='dark'] {
--text-color: #fff;
--bg1: #102128;
--bg2: #2d5567;
}
/* 明亮主题 */
:root {
--text-color: #333;
--bg1: #c7ffdd;
--bg2: #fbd988;
}
/* @media (prefers-color-scheme: dark) { } */
/* @media (prefers-color-scheme: light) {} */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17