import { defineStore } from 'pinia'; import { ref, computed } from 'vue'; // 屏幕检测管理器类 class ScreenDetectionManager { constructor() { this.WIDE_SCREEN_CSS_ID = 'wide-screen-css'; this.WIDE_SCREEN_CSS_PATH = '../common/wide-screen.css'; this.resizeTimer = null; this.resizeListeners = []; this.cssLink = null; } // 获取屏幕宽度 getScreenWidth() { if (typeof window === 'undefined') return 0; // 优先使用 uni.getSystemInfo if (typeof uni !== 'undefined' && uni.getSystemInfo) { return new Promise((resolve) => { uni.getSystemInfo({ success: (res) => { const width = res.screenWidth || res.windowWidth || window.innerWidth; resolve(width); }, fail: () => { resolve(this.getWindowWidth()); } }); }); } return Promise.resolve(this.getWindowWidth()); } // 备用方案:使用 window 对象 getWindowWidth() { if (typeof window === 'undefined') return 0; return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; } // 检测折叠屏 checkVisualViewport() { if (window.visualViewport?.segments?.length > 1) { return { foldable: true, count: window.visualViewport.segments.length - 1 } } else { return { foldable: false, count: 1 } } } // 动态加载 CSS loadWideScreenCSS() { if (typeof window === 'undefined' || this.cssLink) return null; try { this.cssLink = document.createElement('link'); this.cssLink.id = this.WIDE_SCREEN_CSS_ID; this.cssLink.rel = 'stylesheet'; this.cssLink.href = this.WIDE_SCREEN_CSS_PATH; // 添加加载成功/失败监听 this.cssLink.onload = () => { console.log('🎨 宽屏 CSS 文件加载成功'); }; this.cssLink.onerror = () => { console.error('❌ 宽屏 CSS 文件加载失败'); this.cssLink = null; }; document.head.appendChild(this.cssLink); return this.cssLink; } catch (error) { console.error('加载 CSS 失败:', error); this.cssLink = null; return null; } } // 移除 CSS removeWideScreenCSS() { if (this.cssLink && this.cssLink.parentNode) { try { this.cssLink.parentNode.removeChild(this.cssLink); this.cssLink = null; console.log('🗑️ 宽屏 CSS 文件已移除'); return true; } catch (error) { console.error('移除 CSS 失败:', error); return false; } } return false; } // 更新 CSS 状态 updateWideScreenCSS(isWideScreen) { if (isWideScreen) { return this.loadWideScreenCSS(); } else { return this.removeWideScreenCSS(); } } //显示/隐藏默认tabbar updateTabbar(isWideScreen){ if(isWideScreen) uni.hideTabBar() else uni.showTabBar() } // 添加 resize 监听器 addResizeListener(callback, delay = 250) { if (typeof window === 'undefined') return () => {}; const handler = () => { clearTimeout(this.resizeTimer); this.resizeTimer = setTimeout(() => { callback(); }, delay); }; window.addEventListener('resize', handler); this.resizeListeners.push({ callback, handler }); // 返回清理函数 return () => this.removeResizeListener(callback); } // 移除 resize 监听器 removeResizeListener(callback) { const index = this.resizeListeners.findIndex(item => item.callback === callback); if (index > -1) { const { handler } = this.resizeListeners[index]; window.removeEventListener('resize', handler); this.resizeListeners.splice(index, 1); } } } // 创建屏幕状态 store const useScreenStore = defineStore('screen', () => { // 状态 const screenWidth = ref(0); const isInitialized = ref(false); const isLoading = ref(false); const foldFeature = ref(false); const foldCount = ref(0); const isWideScreen = computed(() => { return screenWidth.value >= 1080; }); // 添加屏幕分类的计算属性 const screenCategory = computed(() => { const width = screenWidth.value; if (width <= 768) return 'mobile'; if (width <= 1024) return 'tablet'; if (width <= 1440) return 'desktop'; return 'ultra-wide'; }); // 添加更多响应式计算属性 const isMobile = computed(() => screenCategory.value === 'mobile'); const isTablet = computed(() => screenCategory.value === 'tablet'); const isDesktop = computed(() => screenCategory.value === 'desktop' || screenCategory.value === 'ultra-wide'); // 管理器实例 const manager = new ScreenDetectionManager(); // 初始化屏幕检测 const initScreenDetection = async () => { if (isLoading.value || isInitialized.value) return; isLoading.value = true; try { // 检测屏幕状态 const width = await manager.getScreenWidth(); const { foldable, count } = manager.checkVisualViewport(); foldFeature.value = foldable; foldCount.value = count; screenWidth.value = width; isInitialized.value = true; console.log(`📱 屏幕检测完成: ${width}px, 宽屏: ${isWideScreen.value}`); console.log(`是否为折叠屏: ${foldFeature.value},折叠屏数量:${foldCount.value}`); // 根据状态加载或移除 CSS manager.updateWideScreenCSS(isWideScreen.value); manager.updateTabbar(isWideScreen.value); // 设置 resize 监听 setupResizeListener(); return { screenWidth: width, isWideScreen: isWideScreen.value, foldable, count }; } catch (error) { console.error('初始化屏幕检测失败:', error); return null; } finally { isLoading.value = false; } }; // 手动更新屏幕状态 const updateScreenStatus = async () => { try { const width = await manager.getScreenWidth(); const { foldable, count } = manager.checkVisualViewport(); // 保存旧状态 const oldWidth = screenWidth.value; const oldIsWideScreen = isWideScreen.value; const oldFoldable = foldFeature.value; const oldFoldCount = foldCount.value; // 更新状态 screenWidth.value = width; foldFeature.value = foldable; foldCount.value = count; // 检查宽屏状态是否发生变化 if (oldIsWideScreen !== isWideScreen.value) { console.log(`🔄 屏幕状态变化: ${oldIsWideScreen ? '宽屏' : '非宽屏'} -> ${isWideScreen.value ? '宽屏' : '非宽屏'}`); console.log(`屏幕宽度变化: ${oldWidth}px -> ${width}px`); manager.updateWideScreenCSS(isWideScreen.value); manager.updateTabbar(isWideScreen.value); } // 检查折叠屏状态是否发生变化 if (oldFoldable !== foldable || oldFoldCount !== count) { console.log(`折叠屏状态变化: ${oldFoldable ? '是' : '否'}->${foldable ? '是' : '否'}, 折叠数: ${oldFoldCount}->${count}`); } return { screenWidth: width, isWideScreen: isWideScreen.value, foldable, count }; } catch (error) { console.error('更新屏幕状态失败:', error); return null; } }; // 设置 resize 监听 let cleanupResizeListener = () => {}; const setupResizeListener = () => { if (typeof window === 'undefined') return; cleanupResizeListener = manager.addResizeListener(async () => { await updateScreenStatus(); }, 300); }; // 手动触发屏幕检测 const detectScreen = () => { return updateScreenStatus(); }; return { // 状态 foldFeature, foldCount, screenWidth, isInitialized, isLoading, // 响应式计算属性 isWideScreen, screenCategory, isMobile, isTablet, isDesktop, // 方法 initScreenDetection, updateScreenStatus, detectScreen, }; }); export default useScreenStore;