99 >
1010 <div class =" fixed-header" >
1111 <Header v-if =" ! isMobile " />
12- <div v-else class =" mobile-top-bar" >
12+ <div v-else class =" mobile-top-bar" :class = " { 'home-theme-visible': showHomeThemeToggle } " >
1313 <button v-if =" showMobileBack" class =" mobile-icon-btn" type =" button" title =" 返回" @click =" goBack" >
1414 <span class =" mobile-back-icon" >‹</span >
1515 </button >
2222 <div v-if =" mobileSubtitle" class =" mobile-subtitle" >{{ mobileSubtitle }}</div >
2323 </div >
2424
25+ <button v-if =" showHomeThemeToggle" class =" mobile-icon-btn mobile-theme-toggle" type =" button" :title =" themeToggleTitle" @click =" toggleTheme" >
26+ <span class =" mobile-theme-text" >{{ resolvedTheme === THEME_MODE.DARK ? '浅' : '深' }}</span >
27+ </button >
2528 <button class =" mobile-search-pill" type =" button" title =" 搜索" @click =" goSearch" >
2629 <svg class =" mobile-action-icon" ><use href =" #icon-sousuo" ></use ></svg >
2730 <span >搜索</span >
@@ -183,6 +186,7 @@ import { desktopMenuItems, mobilePrimaryItems, mobileMoreGroups } from '@/config
183186import logoPc from ' @/assets/logo-pc.png' ;
184187import logoMobile from ' @/assets/logo-mobile.png' ;
185188import ' @/assets/icon_font/iconfont.js' ;
189+ import { getStoredThemeMode , resolveThemeMode , setStoredThemeMode , THEME_MODE } from ' @/utils/theme' ;
186190
187191export default defineComponent ({
188192 components: {
@@ -202,6 +206,7 @@ export default defineComponent({
202206 const isImmersivePage = computed (() => Boolean (route .meta ? .immersive ));
203207 const showMobileBottomNav = computed (() => route .meta ? .showBottomNav !== false && ! isImmersivePage .value );
204208 const showMobileBack = computed (() => isImmersivePage .value || route .name === ' SearchAggregation' );
209+ const showHomeThemeToggle = computed (() => route .name === ' Home' );
205210 const mobileTitle = computed (() => route .meta ? .title || ' DrPlayer' );
206211 const mobileSubtitle = computed (() => {
207212 if (route .name === ' Home' ) return ' 影视、直播、阅读与工具' ;
@@ -214,6 +219,13 @@ export default defineComponent({
214219 const siderCollapsed = ref (JSON .parse (localStorage .getItem (' sidebar-collapsed' ) || ' false' ));
215220 const mobileMoreOpen = ref (false );
216221 const isMobile = ref (false );
222+ const resolvedTheme = ref (resolveThemeMode (getStoredThemeMode ()));
223+
224+ const themeToggleTitle = computed (() => resolvedTheme .value === THEME_MODE .DARK ? ' 切换到浅色模式' : ' 切换到深色模式' );
225+
226+ const updateThemeState = (event ) => {
227+ resolvedTheme .value = event ? .detail ? .resolvedTheme || resolveThemeMode (getStoredThemeMode ());
228+ };
217229
218230 const menuItems = ref (desktopMenuItems);
219231 const logoSrc = computed (() => isMobile .value ? logoMobile : logoPc);
@@ -242,6 +254,11 @@ export default defineComponent({
242254 mobileMoreOpen .value = ! mobileMoreOpen .value ;
243255 };
244256
257+ const toggleTheme = () => {
258+ const nextMode = resolvedTheme .value === THEME_MODE .DARK ? THEME_MODE .LIGHT : THEME_MODE .DARK ;
259+ resolvedTheme .value = setStoredThemeMode (nextMode);
260+ };
261+
245262 const isRouteActive = (routeName ) => route .name === routeName;
246263
247264 const goBack = () => {
@@ -284,11 +301,14 @@ export default defineComponent({
284301
285302 onMounted (() => {
286303 updateIsMobile ();
304+ updateThemeState ();
287305 window .addEventListener (' resize' , updateIsMobile);
306+ window .addEventListener (' themeChanged' , updateThemeState);
288307 });
289308
290309 onBeforeUnmount (() => {
291310 window .removeEventListener (' resize' , updateIsMobile);
311+ window .removeEventListener (' themeChanged' , updateThemeState);
292312 });
293313
294314 return {
@@ -299,6 +319,7 @@ export default defineComponent({
299319 isImmersivePage,
300320 showMobileBottomNav,
301321 showMobileBack,
322+ showHomeThemeToggle,
302323 mobileTitle,
303324 mobileSubtitle,
304325 menuItems,
@@ -308,6 +329,10 @@ export default defineComponent({
308329 isMoreRouteActive,
309330 logoSrc,
310331 logoDesc,
332+ resolvedTheme,
333+ themeToggleTitle,
334+ THEME_MODE ,
335+ toggleTheme,
311336 onClickMenuItem,
312337 onSiderCollapse,
313338 closeMobileMore,
@@ -538,6 +563,10 @@ export default defineComponent({
538563 background: var (-- dp- bg- shell);
539564}
540565
566+ .mobile - top- bar .home - theme- visible {
567+ grid- template- columns: 40px minmax (0 , 1fr ) 36px minmax (76px , auto) 40px ;
568+ }
569+
541570.mobile - brand,
542571.mobile - icon- btn {
543572 width: 36px ;
@@ -571,6 +600,17 @@ export default defineComponent({
571600 box- shadow: inset 0 0 0 1px rgba (255 , 255 , 255 , 0.45 );
572601}
573602
603+ .mobile - theme- toggle {
604+ border: 1px solid var (-- dp- border- subtle);
605+ color: var (-- dp- primary- readable);
606+ font- weight: 800 ;
607+ }
608+
609+ .mobile - theme- text {
610+ font- size: 13px ;
611+ line- height: 1 ;
612+ }
613+
574614.mobile - brand- logo {
575615 width: 24px ;
576616 height: 24px ;
0 commit comments