You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vuetify导航抽屉滚动至页脚时顶部隐藏问题求助

问题描述

滚动到页面底部显示页脚时,不希望v-navigation-drawer的顶部被隐藏。

滚动状态对比

  • 滚动前状态:
    滚动前导航栏状态
  • 滚动至底部状态:
    滚动至底部导航栏状态

相关代码

<template>
  <div id="app">
    <v-app>
      <v-app-bar>header</v-app-bar>
      <div class="d-flex flex-0-1-100">
        <v-navigation-drawer
          border="r"
          permanent
          fixed
          class="pa-1 position-sticky"
          style="max-height: calc(100vh - 64px)"
        >
          <div style="border: 2px solid pink; height: 100%">
            nav bar
            <v-text-field
              v-model.number="contentHeight"
              min="0"
              step="400"
              type="number"
              label="content height (px)"
            />
          </div>
        </v-navigation-drawer>
        <v-main class="bg-grey pl-0">
          Main content
          <div
            :style="{height: contentHeight + 'px'}"
            class="bg-brown-darken-2"
          >
            content ({{contentHeight}}px)
          </div>
        </v-main>
      </div>
      <v-footer border="t">footer</v-footer>
    </v-app>
  </div>
</template>
<script setup>
  import { ref } from 'vue'
  const contentHeight = ref(1000)
</script>

可通过Vuetify在线编辑器查看运行效果。

已尝试方案

移除v-navigation-drawer的position-sticky类后,滚动到页脚时导航顶部不再上移,但导航会横向超出页脚边界:
移除sticky后的效果

期望效果

实现类似索尼Pro Bravia指南网站的滚动布局:导航栏始终固定在顶部下方,滚动到页脚时不会被顶部隐藏,也不会超出页脚边界。

当前开发中的额外问题

使用以下v-navigation-drawer代码时,导航高度被减半:

<client-only>
    <v-navigation-drawer
      permanent
      class="position-sticky"
      :style="{ maxHeight, minWidth }"
      style="
        height: fit-content;
        margin-top: 64px;
      "
      width="250"
    >
      <v-row justify="center">
        <v-expansion-panels :modelValue="panel" :multiple="true">
          <v-expansion-panel
            v-for="(item, i) in matchedNavObject.children"
            :key="i"
          >
            <v-expansion-panel-title>{{ item.title }}</v-expansion-panel-title>
            <v-expansion-panel-text
              v-for="(navItem, j) in item.children"
              :key="j"
            >
              <nuxt-link
                :to="`${baseUrl}${navItem._path}`"
                class="text-decoration-none"
                :class="{
                  active: `${navItem._path}/` === route.path,
                }"
                >{{ navItem.title }}</nuxt-link
              >
            </v-expansion-panel-text>
          </v-expansion-panel>
        </v-expansion-panels>
      </v-row>
    </v-navigation-drawer>
  </client-only>

导航高度减半效果


解决方案

核心思路

让导航栏的粘性定位基于v-app内部的主容器,同时限制导航栏的最大高度为「视口高度 - 头部高度 - 页脚高度」,确保滚动到页脚时导航不会超出边界。

代码调整(针对第一个示例)

  1. 移除v-navigation-drawer的fixed属性,调整position-sticky的定位参考
  2. 修正导航栏的高度计算,加入页脚高度
  3. 给导航内部内容添加滚动容器,避免内容溢出

修改后的代码:

<template>
  <div id="app">
    <v-app>
      <v-app-bar>header</v-app-bar>
      <!-- 父容器设为relative,作为粘性导航的定位参考 -->
      <div class="d-flex flex-0-1-100" style="position: relative; min-height: calc(100vh - 64px)">
        <v-navigation-drawer
          border="r"
          permanent
          class="pa-1"
          <!-- 最大高度=视口高度-头部高度-页脚高度(页脚高度需根据实际调整) -->
          style="max-height: calc(100vh - 64px - 48px); position: sticky; top: 64px;"
        >
          <div style="border: 2px solid pink; height: 100%; overflow-y: auto;">
            nav bar
            <v-text-field
              v-model.number="contentHeight"
              min="0"
              step="400"
              type="number"
              label="content height (px)"
            />
          </div>
        </v-navigation-drawer>
        <v-main class="bg-grey pl-0">
          Main content
          <div
            :style="{height: contentHeight + 'px'}"
            class="bg-brown-darken-2"
          >
            content ({{contentHeight}}px)
          </div>
        </v-main>
      </div>
      <v-footer border="t" style="height: 48px;">footer</v-footer>
    </v-app>
  </div>
</template>
<script setup>
  import { ref } from 'vue'
  const contentHeight = ref(1000)
</script>

针对开发中的导航高度问题调整

移除height: fit-content,改用max-height配合滚动容器,同时保证top和margin-top值一致:

<client-only>
    <v-navigation-drawer
      permanent
      class="position-sticky"
      :style="{ maxHeight: `calc(100vh - 64px - 48px)`, minWidth }"
      style="
        top: 64px;
        margin-top: 64px;
        overflow-y: auto;
      "
      width="250"
    >
      <v-row justify="center">
        <v-expansion-panels :modelValue="panel" :multiple="true">
          <v-expansion-panel
            v-for="(item, i) in matchedNavObject.children"
            :key="i"
          >
            <v-expansion-panel-title>{{ item.title }}</v-expansion-panel-title>
            <v-expansion-panel-text
              v-for="(navItem, j) in item.children"
              :key="j"
            >
              <nuxt-link
                :to="`${baseUrl}${navItem._path}`"
                class="text-decoration-none"
                :class="{
                  active: `${navItem._path}/` === route.path,
                }"
                >{{ navItem.title }}</nuxt-link
              >
            </v-expansion-panel-text>
          </v-expansion-panel>
        </v-expansion-panels>
      </v-row>
    </v-navigation-drawer>
  </client-only>

关键说明

  • position: sticky的top值必须和margin-top一致,确保导航始终固定在头部下方
  • 计算max-height时必须包含页脚高度,避免导航超出页脚边界
  • 给导航内部内容添加overflow-y: auto,当内容过长时可滚动,不会撑破容器

内容的提问来源于stack exchange,提问作者shinya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:43:18