110 lines
2.4 KiB
TypeScript
110 lines
2.4 KiB
TypeScript
|
|
import { ref, onMounted, onUnmounted } from 'vue';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设备类型枚举
|
|||
|
|
*/
|
|||
|
|
export enum DeviceType {
|
|||
|
|
MOBILE = 'mobile', // h5移动端
|
|||
|
|
DESKTOP = 'desktop' // web桌面端
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 屏幕尺寸断点
|
|||
|
|
*/
|
|||
|
|
export const BREAKPOINTS = {
|
|||
|
|
mobile: 768, // 小于768px为移动端(h5)
|
|||
|
|
desktop: 768 // 大于等于768px为桌面端(web)
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检测当前设备类型
|
|||
|
|
*/
|
|||
|
|
export function getDeviceType(): DeviceType {
|
|||
|
|
const width = window.innerWidth;
|
|||
|
|
|
|||
|
|
if (width < BREAKPOINTS.mobile) {
|
|||
|
|
return DeviceType.MOBILE; // h5移动端
|
|||
|
|
} else {
|
|||
|
|
return DeviceType.DESKTOP; // web桌面端
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检测是否为移动端
|
|||
|
|
*/
|
|||
|
|
export function isMobile(): boolean {
|
|||
|
|
return getDeviceType() === DeviceType.MOBILE;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检测是否为桌面端
|
|||
|
|
*/
|
|||
|
|
export function isDesktop(): boolean {
|
|||
|
|
return getDeviceType() === DeviceType.DESKTOP;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 响应式设备类型 Hook
|
|||
|
|
*/
|
|||
|
|
export function useDevice() {
|
|||
|
|
const deviceType = ref<DeviceType>(getDeviceType());
|
|||
|
|
const isMobileDevice = ref(isMobile());
|
|||
|
|
const isDesktopDevice = ref(isDesktop());
|
|||
|
|
|
|||
|
|
const updateDeviceType = () => {
|
|||
|
|
deviceType.value = getDeviceType();
|
|||
|
|
isMobileDevice.value = isMobile();
|
|||
|
|
isDesktopDevice.value = isDesktop();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
onMounted(() => {
|
|||
|
|
window.addEventListener('resize', updateDeviceType);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
onUnmounted(() => {
|
|||
|
|
window.removeEventListener('resize', updateDeviceType);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
deviceType,
|
|||
|
|
isMobileDevice,
|
|||
|
|
isDesktopDevice
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 根据设备类型获取对应的组件路径
|
|||
|
|
*/
|
|||
|
|
export function getComponentPath(basePath: string, deviceType?: DeviceType): string {
|
|||
|
|
const currentDeviceType = deviceType || getDeviceType();
|
|||
|
|
|
|||
|
|
// 如果是移动端(h5),尝试加载移动端版本
|
|||
|
|
if (currentDeviceType === DeviceType.MOBILE) {
|
|||
|
|
const mobilePath = basePath.replace('.vue', '.mobile.vue');
|
|||
|
|
return mobilePath;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 默认返回桌面版本(web)
|
|||
|
|
return basePath;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 动态导入组件,支持回退机制
|
|||
|
|
*/
|
|||
|
|
export async function importResponsiveComponent(basePath: string) {
|
|||
|
|
const deviceType = getDeviceType();
|
|||
|
|
|
|||
|
|
// 尝试加载设备特定的组件
|
|||
|
|
if (deviceType === DeviceType.MOBILE) {
|
|||
|
|
try {
|
|||
|
|
const mobilePath = basePath.replace('.vue', '.mobile.vue');
|
|||
|
|
return await import(/* @vite-ignore */ mobilePath);
|
|||
|
|
} catch {
|
|||
|
|
// 移动端组件不存在,回退到默认组件
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 加载默认组件(桌面端/web)
|
|||
|
|
return await import(/* @vite-ignore */ basePath);
|
|||
|
|
}
|