如何让 Vue b-table 滚动带有固定标题的正文
Posted
技术标签:
【中文标题】如何让 Vue b-table 滚动带有固定标题的正文【英文标题】:How to get a Vue b-table to scroll the body with a fixed header 【发布时间】:2018-08-09 21:57:29 【问题描述】:我在一个页面上有一个b-table
元素,该元素当前显示来自数据库的一堆数据。目前它是分页的,但反馈表明他们宁愿将所有信息显示在一个滚动视图中。我可以这样做,但问题是如果我设置一个包含 div
来滚动整个表格,它也会滚动列标题。我需要找到一种方法,以便能够在保留列标题的同时仅滚动表格主体,而且我更希望能够在元素本身的范围内执行此操作,而不是使用完全独立的标题来装配某些东西和身体在后台有一堆 javascript 绑定。
在bootstrap-vue table component 的组件引用下,它说有一个名为tbody-class
的属性,它看起来像是为tbody 指定自定义类的一种方法(够疯狂的)。但是,该页面没有说明如何使用它,而且我的实验也没有产生任何结果:
<b-table
tbody-class="my-class" <- Applies prop to table but not to tbody
:tbody-class="my-class" <- Seemingly ignored entirely
>
听起来此类问题已在 this issue thread 上解决,但并没有真正详细说明如何解决。它提到该功能已添加到“下一次更新”中,但是在该评论之后发布的版本的补丁说明和文档都没有提到该添加(除非它意味着我在上一段中提到的属性)。它确实谈到了使用 CSS 选择器以迂回的方式应用样式,但我也无法让它工作。 (在以下示例中,Chrome 检查器中的tbody
没有应用的样式。)
.table.my-table > tbody
height: 100px;
我使用的 Vue 版本是 2.2.6。
【问题讨论】:
呃,玩this fiddle,表格会忽略你放在上面的任何CSS。 你试过:tbody-class="'my-class'"
或:tbody-class="['my-class']"
吗?它期望 tbody-class 为 String or Array
@JacobGoh :tbody-class="'my-class'"
和 :tbody-class="['my-class']"
似乎都被解释为 :tbody-class="my-class"
。如果我添加另一个元素,如:tbody-class="['my-class','my-other-class']"
,那么 that 似乎只是变成了:tbody-class="my-class,my-other-class"
。我认为这就是“字符串或数组”的含义。
(我无法发布 cmets,所以这是一个答案) 向下滚动比页面长的表格时,固定标题很有用。引导表提供了一种避免完全向下滚动的方法:pagination。这不能回答问题,但它可能会解决问题(它对我有影响)。
@fredericf 第二句表示分页不是一个理想的选项。
【参考方案1】:
我需要找到一种方法,以便在保留列标题的同时仅滚动表格主体,而且我更希望能够在元素本身的范围内执行此操作,而不是使用完全分离标题和正文,在后台使用一堆 Javascript 绑定
我为您创建了一个example repository 以了解如何使其工作(也有隐藏的滚动条)。
可能还有其他方法可以完成同样的事情,但这就是我所做的。
<!-- wrap table in container with class. -->
<b-container fluid class="table-container">
<b-table
:items="items"
:fields="fields"
caption-top
>
</b-table>
</b-container>
这是带有隐藏滚动条的 CSS。
.table-container
height: calc(100vh - 450px);
.table-container table
display: flex;
flex-flow: column;
height: 100%;
width: 100%;
.table-container table thead
flex: 0 0 auto;
width: 100%;
.table-container table tbody
flex: 1 1 auto;
display: block;
width: 100%;
overflow-y: auto;
.table-container table tbody tr
width: 100%;
.table-container table thead, .table-container table tbody tr
display: table;
table-layout: fixed;
.table-container table
border-collapse: collapse;
.table-container table td, .table-container table th
padding: 0.4em;
.table-container table th
border: 1px solid black;
font-size: 0.7vw;
.table-container table td
border: 1px solid #e7e1e1;
font-size: 0.85em;
/* necessary to set for proper "showing row x of y" calculations if infinate scoll */
white-space: nowrap;
text-align: center;
padding: 10px 5px;
white-space: nowrap;
text-overflow: ellipsis;
.table-container table thead
border: 2px solid #0F0FA3;
.table-container th
background-color: #0F0FA3;
color: #b5aba4;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none !important;
-ms-user-select: none;
user-select: none;
.table-container table tbody td
padding: 8px;
cursor: pointer;
.table-container table tbody tr:hover
background-color: rgba(168, 168, 239, .5);
.table-container table thead td
padding: 10px 5px;
.table-container tr:nth-child(even)
background-color: rgba(168, 168, 239, 1);
/* START Adjustments for width and scrollbar hidden */
.table-container th.table-action, .table-container td.table-action
width: 5.8vw;
.table-container table thead
width: calc(100% - 1px);
.table-container table tbody::-webkit-scrollbar
width: 1px;
.table-container table tbody::-webkit-scrollbar
width: 1px;
.table-container table tbody::-webkit-scrollbar-thumb
width: 1px;
/* END Adjustments for width and scrollbar */
更新,另一种固定标题但非常受限的方法(ref):
有几种方法可以做到这一点......跨浏览器不是 始终保证:
创建一个类,比如 my-table-scroll
table.my-table-scroll,
table.my-table-scroll > thead,
table.my-table-scroll > tbody,
table.my-table-scroll > tfoot,
table.my-table-scroll > tbody > tr,
table.my-table-scroll > thead > tr
width: 100%;
display: block
table.my-table-scroll > thead,
table.my-table-scroll > tbody,
table.my-table-scroll > tfoot
display: block;
width: 100%;
overflow-y: scroll;
table.my-table-scroll > thead,
table.my-table-scroll > tfoot
height: auto;
/* these last two rules you will need to tweak on an as needed basis */
table.my-table-scroll > tbody
/* set max height for tbody before it scrolls */
max-height: 200px;
table.my-table-scroll > thead > tr > th,
table.my-table-scroll > thead > tr > td,
table.my-table-scroll > tbody > tr > th,
table.my-table-scroll > tbody > tr > td,
table.my-table-scroll > tfoot > tr > th,
table.my-table-scroll > tfoot > tr > td
display: inline-block;
/* you need to explicitly specify the width of the table cells */
/* either equal, or specify individual widths based on col index. */
/* Here, we assume you have 4 columns of data */
width: 25%;
/*
could use sibling selectors to select specific columns for widths:
td + td (second column)
td + td + td (3rd column, etc)
*/
然后将类放到你的 b-table 上。
【讨论】:
【参考方案2】:从v2.0.0-rc.28 开始,添加了可选属性sticky-header
以支持固定标头。
new Vue(
el: '#app',
data:
items: [
heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' ,
heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' ,
heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' ,
heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' ,
heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' ,
heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' ,
heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' ,
heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' ,
heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' ,
heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' ,
heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' ,
heading1: 'table cell', heading2: 'table cell', heading3: 'table cell'
],
);
<html>
<header>
<script src="//unpkg.com/vue@2.6.11/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@2.0.0/dist/bootstrap-vue.js"></script>
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap@4.3.1/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@2.0.0/dist/bootstrap-vue.min.css" />
</header>
<body>
<div id="app">
<b-table sticky-header :items="items" head-variant="light"></b-table>
</div>
</body>
</html>
【讨论】:
以上是关于如何让 Vue b-table 滚动带有固定标题的正文的主要内容,如果未能解决你的问题,请参考以下文章
Bootstrap-vue b-table:如何为非活动行设置 css-Class?
Vue-Bootstrap:如何触发一个 b-table 的排序以触发另一个 b-table 的排序?