-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
Copy pathApp.vue
144 lines (140 loc) · 4.33 KB
/
App.vue
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<template>
<a-style-provider :hash-priority="hashPriority">
<a-config-provider :locale="locale" :theme="themeConfig">
<SiteToken>
<router-view />
</SiteToken>
</a-config-provider>
</a-style-provider>
</template>
<script lang="ts">
import { computed, defineComponent, provide, watch, ref } from 'vue';
import type { Ref } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import useMediaQuery from './hooks/useMediaQuery';
import { GLOBAL_CONFIG } from './SymbolKey';
import enUS from '../../components/locale/en_US';
import zhCN from '../../components/locale/zh_CN';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import { theme as antdTheme } from 'ant-design-vue';
import SiteToken from './SiteToken.vue';
function isZhCN(name: string) {
return /-cn\/?$/.test(name);
}
export interface GlobalConfig {
isMobile: Ref<boolean>;
lang: Ref<'zh-CN' | 'en-US'>;
isZhCN: Ref<boolean>;
responsive: Ref<null | 'narrow' | 'crowded'>;
blocked: Ref<boolean>;
}
export type ThemeName = '' | 'light' | 'dark' | 'compact';
const getAlgorithm = (themes: ThemeName[] = []) =>
themes
.filter(theme => !!theme)
.map(theme => {
if (theme === 'dark') {
return antdTheme.darkAlgorithm;
}
if (theme === 'compact') {
return antdTheme.compactAlgorithm;
}
return antdTheme.defaultAlgorithm;
});
export default defineComponent({
components: {
SiteToken,
},
setup() {
const route = useRoute();
const i18n = useI18n();
const colSize = useMediaQuery();
const isMobile = computed(() => colSize.value === 'sm' || colSize.value === 'xs');
const theme = ref<ThemeName>((localStorage.getItem('theme') as ThemeName) || 'light');
const compactTheme = ref<ThemeName>((localStorage.getItem('compactTheme') as ThemeName) || '');
const themeConfig = computed(() => {
return { algorithm: getAlgorithm([...new Set([theme.value, compactTheme.value])]) };
});
const hashPriority = ref('low' as const);
watch(hashPriority, () => {
location.reload();
});
// useSiteToken();
const responsive = computed(() => {
if (colSize.value === 'xs') {
return 'crowded';
} else if (colSize.value === 'sm') {
return 'narrow';
}
return null;
});
const globalConfig: GlobalConfig = {
isMobile,
responsive,
lang: computed<any>(() => i18n.locale.value),
isZhCN: computed(() => i18n.locale.value === 'zh-CN'),
blocked: ref(false),
};
const changeTheme = (t: ThemeName) => {
theme.value = t;
localStorage.setItem('theme', t);
};
const changeCompactTheme = (t: ThemeName) => {
compactTheme.value = t;
localStorage.setItem('compactTheme', t);
};
provide('themeMode', {
theme,
compactTheme,
changeTheme,
changeCompactTheme,
});
provide(GLOBAL_CONFIG, globalConfig);
watch(
() => route.path,
val => {
i18n.locale.value = isZhCN(val) ? 'zh-CN' : 'en-US';
},
{ immediate: true },
);
watch(
globalConfig.isZhCN,
val => {
if (val) {
dayjs.locale(zhCN.locale);
} else {
dayjs.locale(enUS.locale);
}
},
{ immediate: true },
);
const locale = computed(() => {
return globalConfig.isZhCN.value ? zhCN : enUS;
});
setTimeout(() => {
const div = document.createElement('div');
div.className = 'adsbox';
document.body.appendChild(div);
globalConfig.blocked.value = 'none' === getComputedStyle(div).display;
}, 300);
watch(
theme,
() => {
if (theme.value === 'dark') {
document.getElementsByTagName('html')[0].setAttribute('data-doc-theme', 'dark');
document.getElementsByTagName('body')[0].setAttribute('data-theme', 'dark');
document.getElementsByTagName('html')[0].style.colorScheme = 'dark';
} else {
document.getElementsByTagName('html')[0].setAttribute('data-doc-theme', 'light');
document.getElementsByTagName('body')[0].setAttribute('data-theme', 'light');
document.getElementsByTagName('html')[0].style.colorScheme = 'light';
}
},
{ immediate: true },
);
return { globalConfig, locale, themeConfig, hashPriority };
},
});
</script>