- 侧边栏在窄屏改为抽屉:汉堡按钮唤起、遮罩点击关闭、切换路由自动收起 - 页头纵向排列,操作按钮与筛选控件撑满一行 - 对话框改用视口百分比宽度,表单标签改为顶部对齐,内容区限高可滚动 - 表格隐藏次要列并把操作列固定在右侧,仍可横向滚动查看全部 - 仪表盘倒计时环与信息上下排列,统计卡改两列 - 分页器在窄屏收缩为精简布局 - 输入框字号提到 16px,避免 iOS Safari 聚焦时自动缩放 - 新增 useIsMobile composable 处理 CSS 覆盖不到的部分 顺带修复汉堡按钮在桌面端未隐藏:.menu-btn 与后声明的 .icon-btn 特异性相同被覆盖,改用 .icon-btn.menu-btn 复合选择器。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
37 lines
1.1 KiB
TypeScript
37 lines
1.1 KiB
TypeScript
import { onUnmounted, ref } from 'vue'
|
|
|
|
/** 移动端断点,与 main.css 中的媒体查询保持一致 */
|
|
export const MOBILE_BREAKPOINT = 768
|
|
|
|
/**
|
|
* 响应式的移动端判断。
|
|
*
|
|
* 用于那些光靠 CSS 改不了的地方,比如表格列的显隐、分页器布局、表单标签位置。
|
|
*
|
|
* 除了监听 matchMedia 的 change,额外挂一个 resize 兜底:
|
|
* 某些环境(内嵌 WebView、开发者工具的设备模拟)改视口时不会派发 change,
|
|
* 只靠 change 会导致旋转屏幕后布局不跟着变。
|
|
*/
|
|
export function useIsMobile() {
|
|
const query = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT}px)`)
|
|
const isMobile = ref(query.matches)
|
|
|
|
const sync = () => {
|
|
if (isMobile.value !== query.matches) {
|
|
isMobile.value = query.matches
|
|
}
|
|
}
|
|
|
|
query.addEventListener('change', sync)
|
|
window.addEventListener('resize', sync, { passive: true })
|
|
window.addEventListener('orientationchange', sync)
|
|
|
|
onUnmounted(() => {
|
|
query.removeEventListener('change', sync)
|
|
window.removeEventListener('resize', sync)
|
|
window.removeEventListener('orientationchange', sync)
|
|
})
|
|
|
|
return isMobile
|
|
}
|