diff --git a/frontend/src/mobile/useDevice.ts b/frontend/src/mobile/useDevice.ts new file mode 100644 index 0000000..1618a0c --- /dev/null +++ b/frontend/src/mobile/useDevice.ts @@ -0,0 +1,51 @@ +// src/mobile/useDevice.ts +// 设备检测:判断当前是否移动端,结果存 localStorage 避免重复检测 + +const STORAGE_KEY = 'device_mode' + +/** UA 关键字匹配移动设备 */ +const MOBILE_UA = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i + +/** 屏幕宽度阈值(含平板竖屏) */ +const MOBILE_WIDTH = 768 + +/** + * 原始检测:综合 UA 和屏幕宽度判断 + * - UA 命中移动设备关键字 → 手机 + * - 屏宽 <= 768 → 手机 + * - 否则 → 桌面 + */ +function detectRaw(): 'mobile' | 'desktop' { + if (typeof navigator === 'undefined') return 'desktop' + if (MOBILE_UA.test(navigator.userAgent)) return 'mobile' + if (typeof window !== 'undefined' && window.innerWidth <= MOBILE_WIDTH) return 'mobile' + return 'desktop' +} + +/** 当前设备模式(读取 localStorage,无则检测并存入) */ +export function getDeviceMode(): 'mobile' | 'desktop' { + if (typeof localStorage === 'undefined') return detectRaw() + const stored = localStorage.getItem(STORAGE_KEY) + if (stored === 'mobile' || stored === 'desktop') return stored + const detected = detectRaw() + localStorage.setItem(STORAGE_KEY, detected) + return detected +} + +/** 是否移动端(路由分流用,同步函数) */ +export function isMobile(): boolean { + return getDeviceMode() === 'mobile' +} + +/** + * 手动切换设备模式(设置页"切换到桌面版/手机版"用) + * 切换后需整页刷新以重新走路由解析 + */ +export function setDeviceMode(mode: 'mobile' | 'desktop') { + localStorage.setItem(STORAGE_KEY, mode) +} + +/** 重置为自动检测(登出时调用,避免下个用户沿用上个用户的偏好) */ +export function resetDeviceMode() { + localStorage.removeItem(STORAGE_KEY) +} diff --git a/frontend/src/views-mobile/Placeholder.vue b/frontend/src/views-mobile/Placeholder.vue new file mode 100644 index 0000000..6bbe831 --- /dev/null +++ b/frontend/src/views-mobile/Placeholder.vue @@ -0,0 +1,31 @@ + + + + + + +