# 布局模式参考

## 标准页面骨架

```vue
<template>
  <v-container fluid class="d-flex flex-column h-100 pa-0">
    <!-- 固定头部 -->
    <v-toolbar density="compact" class="flex-shrink-0">
      <v-toolbar-title>页面标题</v-toolbar-title>
      <v-spacer />
      <v-btn icon="mdi-refresh" @click="refresh" />
    </v-toolbar>

    <!-- 可滚动内容区 -->
    <div class="flex-grow-1 overflow-y-auto pa-4" style="min-height: 0">
      <slot />
    </div>

    <!-- 固定底部（可选） -->
    <v-footer app class="flex-shrink-0">
      <v-btn block color="primary">操作</v-btn>
    </v-footer>
  </v-container>
</template>
```

## Flexbox 滚动陷阱解决方案

```css
/* 问题：子元素撑破父容器 */
.parent {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.content {
  flex-grow: 1;
  /* 必须添加以下任一属性 */
  min-height: 0;        /* 推荐 */
  /* 或 */
  overflow: hidden;
}
```

## 粘性筛选栏

```vue
<template>
  <div class="flex-grow-1 overflow-y-auto" style="min-height: 0">
    <!-- 粘性筛选区 -->
    <div class="sticky-top bg-surface pa-4" style="z-index: 1">
      <v-row>
        <v-col cols="4">
          <v-text-field v-model="search" label="搜索" />
        </v-col>
        <v-col cols="4">
          <v-select v-model="status" :items="statusOptions" label="状态" />
        </v-col>
      </v-row>
    </div>

    <!-- 列表内容 -->
    <v-list>...</v-list>
  </div>
</template>

<style scoped>
.sticky-top {
  position: sticky;
  top: 0;
}
</style>
```

## 分栏布局（侧边栏 + 主内容）

```vue
<template>
  <div class="d-flex h-100">
    <!-- 固定宽度侧边栏 -->
    <v-navigation-drawer permanent width="280">
      <v-list nav>...</v-list>
    </v-navigation-drawer>

    <!-- 自适应主内容 -->
    <div class="flex-grow-1 d-flex flex-column" style="min-width: 0">
      <v-toolbar>主内容头部</v-toolbar>
      <div class="flex-grow-1 overflow-y-auto pa-4" style="min-height: 0">
        主内容区域
      </div>
    </div>
  </div>
</template>
```

## 双栏详情布局

```vue
<template>
  <div class="d-flex flex-column h-100">
    <v-toolbar density="compact" class="flex-shrink-0">
      <v-btn icon="mdi-arrow-left" @click="goBack" />
      <v-toolbar-title>详情</v-toolbar-title>
    </v-toolbar>

    <div class="flex-grow-1 d-flex" style="min-height: 0">
      <!-- 左侧主信息 -->
      <div class="flex-grow-1 overflow-y-auto pa-4" style="min-width: 0">
        <v-card>...</v-card>
      </div>

      <!-- 右侧边栏 -->
      <v-sheet width="320" class="flex-shrink-0 overflow-y-auto border-s">
        <v-list>相关信息</v-list>
      </v-sheet>
    </div>
  </div>
</template>
```

## Tab 切换布局

```vue
<template>
  <div class="d-flex flex-column h-100">
    <v-tabs v-model="activeTab" class="flex-shrink-0">
      <v-tab value="info">基本信息</v-tab>
      <v-tab value="logs">操作日志</v-tab>
      <v-tab value="settings">设置</v-tab>
    </v-tabs>

    <v-divider />

    <v-tabs-window v-model="activeTab" class="flex-grow-1" style="min-height: 0">
      <v-tabs-window-item value="info" class="h-100 overflow-y-auto">
        <!-- 内容 -->
      </v-tabs-window-item>
      <v-tabs-window-item value="logs" class="h-100 overflow-y-auto">
        <!-- 内容 -->
      </v-tabs-window-item>
      <v-tabs-window-item value="settings" class="h-100 overflow-y-auto">
        <!-- 内容 -->
      </v-tabs-window-item>
    </v-tabs-window>
  </div>
</template>
```

## 响应式断点处理

```vue
<script setup lang="ts">
import { useDisplay } from 'vuetify'

const { mobile, mdAndUp, lgAndUp } = useDisplay()

// 根据屏幕尺寸调整列数
const gridCols = computed(() => {
  if (lgAndUp.value) return 4
  if (mdAndUp.value) return 3
  return 2
})
</script>

<template>
  <v-row>
    <v-col v-for="item in items" :key="item.id" :cols="12 / gridCols">
      <v-card>...</v-card>
    </v-col>
  </v-row>

  <!-- 移动端特殊处理 -->
  <v-bottom-navigation v-if="mobile" grow>
    <v-btn value="home">
      <v-icon>mdi-home</v-icon>
      <span>首页</span>
    </v-btn>
  </v-bottom-navigation>
</template>
```
