使用 Vuetify + Electron 固定 header 下面的滚动条

Scroll bar below fixed header with Vuetify + Electron

我正在使用 Vuetify 和 Electron 制作一个应用程序来帮助我完成工作中的某些任务。我已经禁用了 browserWindow 框架,并使我的 header 成为可拖动区域,并带有一个按钮来关闭 window。我正在使用 electron vuetify 模板

vue init vuetifyjs/electron

我的问题是滚动条一直延伸到顶部,但我希望它低于我固定的 header。

我尝试在 html、body、应用程序 div 和内容 div 标签上使用溢出属性,但我没有成功。

我该如何完成?

这纯粹是一个 CSS 问题,因为您也可以在具有类似布局的浏览器中看到这种行为。解决此问题的最简单方法是使用弹性布局:

HTML:

<div class="container">
  <div class="titlebar"></div>
  <div class="content">
    <h1>So much content we scroll</h1>
    <h1>So much content we scroll</h1>
    <!-- etc -->
  </div>
</div>

CSS:

body {
    margin: 0;
    padding: 0;
    overflow: hidden;
}

.container {
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.titlebar {
  background-color: blue;
  height: 35px;
  flex-shrink: 0;
}

.content {
  flex-grow: 1;
  overflow-x: auto;
}

看看这个 CodePen

我想为这个问题提供一个 Vuetify 特定的答案,无论是否涉及 Electron,这都应该适用。

Vuetify 的默认样式使这比简单的 CSS 解决方案更难,尤其是当布局变得更复杂时。

对于这个例子,我使用了来自 Vuetify 的 pre-defined 主题的复杂布局 here

Vuetify 附带一个 overflow-y:在 html 元素上滚动,因此第一步是为此添加覆盖。

html {
  overflow: hidden;
}

这将消除右侧横跨应用程序整个高度的栏。

接下来您需要将 v-content 区域设置为可滚动区域。设置此区域时需要注意一些问题:

  • 已声明显示 flex
  • Vuetify 在样式属性中设置填充,因此您需要根据您的情况进行覆盖
  • 您需要为 header 的高度留出边距(仅当您将 header 高度从 64px 更改时才重要)
  • 您需要使用 calc 从内容容器的高度中移除 header 高度(同上)
  • 如果右侧有导航抽屉,则需要绑定 class 来解决这个问题。

我的 CSS for v-content 看起来像这样,你需要一个重要的来覆盖填充,因为它是由 Vuetify 通过样式绑定设置的:

main.v-content {
  width: 100vw;
  height: calc(100vh - 64px);
  flex-direction: column;
  overflow: scroll;
  margin-top: 64px;
  padding-top: 0 !important;
}

我还有一个 class 绑定到模板中 v-content 标签上的临时右侧抽屉的状态,这确保滚动条不会在右侧导航下方消失打开时的抽屉:

<v-content :class="{ draweropen: drawerRight }">

和那个绑定 class 的 CSS,你需要再次删除抽屉打开时 Vuetify 放在 v-content 上的默认右填充:

.draweropen {
  width: calc(100vw - 300px) !important;
  padding-right: 0 !important;
}

如果您的内容像聊天一样底部加载,您可以选择将 flex-direction 设置为 column-reverse,这正是我在此 CodePen Example

中所做的

我构建了一个包裹 v-main 并将滚动条移动到主容器而不是默认容器(整个 html)的小组件。

只需将 v-main 替换为这个即可。

<template>
  <v-main class="my-main">
    <div class="my-main__scroll-container">
      <slot />
    </div>
  </v-main>
</template>

<script>
export default {
  mounted: function() {
    let elHtml = document.getElementsByTagName('html')[0]
    elHtml.style.overflowY = 'hidden'
  },
  destroyed: function() {
    let elHtml = document.getElementsByTagName('html')[0]
    elHtml.style.overflowY = null
  },
}
</script>

<style>
.my-main
  height: 100vh

.my-main__scroll-container
  height: 100%
  overflow: auto
</style>