zhangnuoyan
2024-08-24 a1f7104959fcefe9940f849456cda934858c5733
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import { ref, onMounted } from "vue";
 
const themeModeOptions = [
    { label: "亮色模式", value: "light" },
    { label: "暗色模式", value: "dark" },
    { label: "定制模式", value: "custom" },
    { label: "跟随系统", value: "auto" }
];
 
const defaultTheme: any = localStorage.getItem("arco-theme") || "auto";
 
const currentTheme = ref<"light" | "dark">(defaultTheme);
const currentThemeMode = ref<"light" | "dark" | "auto" | "custom">(defaultTheme);
 
export const useTheme = () => {
    //设置自动主题模式
    const setAutoTheme = () => {
        if (currentThemeMode.value !== "auto") return;
        localStorage.setItem("arco-theme", "auto");
        const mode = darkModeQuery.matches ? "dark" : "light";
        currentThemeMode.value = "auto";
        currentTheme.value = mode;
        document.body.setAttribute("arco-theme", mode);
    };
 
    //设置手动主题模式
    const setManualTheme = (v: "light" | "dark" | "custom") => {
        localStorage.setItem("arco-theme", v);
        currentThemeMode.value = v;
        currentTheme.value = v;
        document.body.setAttribute("arco-theme", v);
    };
 
    //获取当前浏览器主题色,并监听系统级切换
    const darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)");
    darkModeQuery.addListener(setAutoTheme);
 
    //用于处理手动切换主题
    const handleThemeChange = (v: "light" | "dark" | "auto" | "custom") => {
        if (v === "auto") {
            currentThemeMode.value = "auto";
            setAutoTheme();
        } else {
            setManualTheme(v);
        }
    };
 
    //初始化
    onMounted(() => {
        if (currentThemeMode.value === "auto") {
            currentThemeMode.value = "auto";
            setAutoTheme();
        } else {
            setManualTheme(currentThemeMode.value);
        }
    });
 
    onUnmounted(() => {
        darkModeQuery.removeListener(setAutoTheme);
    });
 
    return {
        currentTheme,
        currentThemeMode,
        themeModeOptions,
        handleThemeChange
    };
};