API 浏览器
表格

QTable 是一个允许你以表格方式显示数据的组件。它通常被称为数据表。它包含以下主要功能:

¥QTable is a component that allows you to display data in a tabular manner. It’s generally called a datatable. It packs the following main features:

  • 过滤

    ¥Filtering

  • 排序

    ¥Sorting

  • 使用自定义选择操作进行单行/多行选择

    ¥Single / Multiple rows selection with custom selection actions

  • 分页(如果需要,包括服务器端)

    ¥Pagination (including server-side if required)

  • 网格模式(例如,你可以使用 QCards 以非表格方式显示数据)

    ¥Grid mode (you can use for example QCards to display data in a non-tabular manner)

  • 通过作用域插槽完全自定义行和单元格

    ¥Total customization of rows and cells through scoped slots

  • 能够在数据行的顶部或底部添加额外行

    ¥Ability to add additional row(s) at top or bottom of data rows

  • 列选择器(通过其中一节中描述的 QTableColumns 组件)

    ¥Column picker (through QTableColumns component described in one of the sections)

  • 自定义顶部和/或底部表格控件

    ¥Custom top and/or bottom Table controls

  • 响应式设计

    ¥Responsive design

提示

如果你不需要 QTable 的分页、排序、过滤和所有其他功能,那么你可能需要查看 QMarkupTable 组件。

¥If you don’t need pagination, sorting, filtering, and all other features of QTable, then you may want to check out QMarkupTable component instead.

Loading QTable API...
Loading QTh API...
Loading QTr API...
Loading QTd API...

定义列(Defining the columns)

¥Defining the columns

让我们以配置 columns 属性为例。我们将告诉 QTable,row-key 是“名称”,它必须是唯一的。如果这是从数据库获取的数据,我们可能会使用行 ID。

¥Let’s take an example of configuring the columns property. We are going to tell QTable that row-key is ‘name’, which must be unique. If this was data fetched from a database we would likely use the row id.

columns: [ // array of Objects
  // column Object definition
  {
    // unique id
    // identifies column
    // (used by pagination.sortBy, "body-cell-[name]" slot, ...)
    name: 'desc',

    // label for header
    label: 'Dessert (100g serving)',

    // row Object property to determine value for this column
    field: 'name',
    // OR field: row => row.some.nested.prop,

    // (optional) if we use visible-columns, this col will always be visible
    required: true,

    // (optional) alignment
    align: 'left',

    // (optional) tell QTable you want this column sortable
    sortable: true,

    // (optional) compare function if you have
    // some custom data or want a specific way to compare two rows
    // --> note that rows with null/undefined as value will get auto sorted
    // without calling this method (if you want to handle those as well, use "rawSort" instead)
    sort: (a, b, rowA, rowB) => parseInt(a, 10) - parseInt(b, 10),
    // function return value:
    //   * is less than 0 then sort a to an index lower than b, i.e. a comes first
    //   * is 0 then leave a and b unchanged with respect to each other, but sorted with respect to all different elements
    //   * is greater than 0 then sort b to an index lower than a, i.e. b comes first

    // (optional) requires Quasar v2.13+
    // compare function if you have
    // some custom data or want a specific way to compare two rows
    // --> note that there is an alternative "sort" method (above) if you don't
    // want to handle (by yourself) rows with null/undefined as value
    rawSort: (a, b, rowA, rowB) => parseInt(a, 10) - parseInt(b, 10),
    // has the same return value as the alternative "sort" method above

    // (optional) override 'column-sort-order' prop;
    // sets column sort order: 'ad' (ascending-descending) or 'da' (descending-ascending)
    sortOrder: 'ad', // or 'da'

    // (optional) you can format the data with a function
    format: (val, row) => `${val}%`,
    // one more format example:
    // format: val => val
    //   ? /* Unicode checkmark checked */ "\u2611"
    //   : /* Unicode checkmark unchecked */ "\u2610",

    // body td:
    style: 'width: 500px',
    // or as Function --> style: row => ... (return String/Array/Object)
    classes: 'my-special-class',
    // or as Function --> classes: row => ... (return String)

    // header th:
    headerStyle: 'width: 500px',
    headerClasses: 'my-special-class'
  },
  { name: 'calories', label: 'Calories', field: 'calories', sortable: true },
  { name: 'fat', label: 'Fat (g)', field: 'fat', sortable: true },
  { name: 'carbs', label: 'Carbs (g)', field: 'carbs' },
  { name: 'protein', label: 'Protein (g)', field: 'protein' },
  { name: 'sodium', label: 'Sodium (mg)', field: 'sodium' },
  { name: 'calcium', label: 'Calcium (%)', field: 'calcium', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) },
  { name: 'iron', label: 'Iron (%)', field: 'iron', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }
]

基本用法(Basic usage)

¥Basic usage

Basic



Force dark mode



Dense



提示

你可以将 dense 属性与 $q.screen 属性一起使用来创建响应式行为。示例::dense="$q.screen.lt.md"。更多信息:屏幕插件

¥You can use the dense prop along with $q.screen to create a responsive behavior. Example: :dense="$q.screen.lt.md". More info: Screen Plugin.

省略列定义(Omitting columns definition)

¥Omitting columns definition

你可以省略指定 columns。QTable 会根据数据第一行的属性推断列。请注意,标签必须大写,并且已启用排序:

¥You can omit specifying the columns. QTable will infer the columns from the properties of the first row of the data. Note that labels are uppercased and sorting is enabled:

Infering columns from data



固定标题/列(Sticky header/column)

¥Sticky header/column

警告

固定标题和列是通过 CSS 和 position: sticky 实现的。并非所有浏览器都支持此功能。使用此技术之前,请先检查 caniuse.com

¥Sticky headers and columns are achieved through CSS with position: sticky. This is NOT supported on all browsers. Check caniuse.com before using this technique.

提示

请注意以下示例中 “style” 部分的代码,尤其是 position: sticky 部分。

¥Pay attention to the code in the “style” section in the following examples, especially around position: sticky.

Sticky header



Sticky first column



Sticky last column



Sticky header and column



Sticky header and last column



分隔符(Separators)

¥Separators

Separators



样式(Styling)

¥Styling

Custom column



提示

要查看所有样式组件属性,请查看页面顶部的 API 卡片。

¥For all the styling component properties, please check the API card at the top of the page.

Custom coloring






虚拟滚动(Virtual scrolling)

¥Virtual scrolling

请注意,启用虚拟滚动时,你需要指定 table-style(带有 max-height)属性。在下面的示例中,我们还强制 QTable 一次显示所有行(注意 paginationrows-per-page-options 属性的使用)。

¥Notice that when enabling virtual scroll you will need to specify the table-style (with a max-height) prop. In the example below, we are also forcing QTable to display all rows at once (note the use of pagination and rows-per-page-options props).

Basic virtual scroll



你可以在滚动到末尾时动态加载新行:

¥You can dynamically load new rows when scroll reaches the end:

Dynamic loading virtual scroll



你可以同时使用虚拟滚动和分页:

¥You can have both virtual scroll and pagination:

Virtual scroll and pagination



以下示例展示了如何将虚拟滚动与粘性标题一起使用。注意 virtual-scroll-sticky-start 属性,它被设置为标题高度。

¥The example below shows how virtual scroll can be used along with a sticky header. Notice the virtual-scroll-sticky-start prop which is set to the header height.

Virtual scroll with sticky header



有两个实用 CSS 类用于控制 VirtualScroll 大小的计算:

¥There are 2 utility CSS classes that control VirtualScroll size calculation:

  • 在 VirtualScroll 渲染的元素上使用 q-virtual-scroll--with-prev 类,以指示该元素应与前一个元素分组(主要用例是从同一行数据生成的多个表格行)。

    ¥Use q-virtual-scroll--with-prev class on an element rendered by the VirtualScroll to indicate that the element should be grouped with the previous one (main use case is for multiple table rows generated from the same row of data).

  • 在 VirtualScroll 渲染的元素上使用 q-virtual-scroll--skip 类,以指示在大小计算中应忽略该元素的大小。

    ¥Use q-virtual-scroll--skip class on an element rendered by the VirtualScroll to indicate that the element’s size should be ignored in size calculations.

Virtual scroll with multiple rows for a data row



选择(Selection)

¥Selection

警告

必须设置属性 row-key 才能使选择功能正常工作。

¥The property row-key must be set in order for selection to work properly.

Single selection



Multiple selection



Selection cell slots



Selection cell slots with range selection



Custom multiple selection



可见列、自定义顶部、全屏(Visible columns, custom top, fullscreen)

¥Visible columns, custom top, fullscreen

请注意,标记为 required 的列(在列定义中)无法切换,并且始终可见。

¥Please note that columns marked as required (in the column definition) cannot be toggled and are always visible.

Visible columns, custom top and fullscreen



Visible columns



弹出窗口编辑(Popup editing)

¥Popup editing

提示

以下是用户能够借助 QPopupEdit 组件进行“就地”编辑的示例。请注意,我们正在使用 body 作用域插槽。QPopupEdit 不支持单元格范围的插槽。

¥Below is an example with the user being able to edit “in place” with the help of QPopupEdit component. Please note that we are using the body scoped slot. QPopupEdit won’t work with cell scoped slots.

Popup editing



使用输入框编辑(Editing with an input)

¥Editing with an input

Input editing



网格样式(Grid style)

¥Grid style

提示

你可以将 grid 属性与 $q.screen 属性一起使用来创建响应式行为。示例::grid="$q.screen.lt.md"。更多信息:屏幕插件

¥You can use the grid prop along with $q.screen to create a responsive behavior. Example: :grid="$q.screen.lt.md". More info: Screen Plugin.

在下面的示例中,我们让 QTable 处理网格模式的显示(不使用特定的插槽):

¥In the example below, we let QTable deal with displaying the grid mode (not using the specific slot):

Grid style



Grid with header



Colored grid style



Masonry like grid



但是,如果你想完全自定义内容,请查看以下示例,其中:

¥However, if you want to fully customize the content, check the example below, where:

  • 我们使用一个名为 item 的 Vue 作用域插槽来定义每条记录(相当于非网格模式下的一行)的外观。这为你提供了完全的自由。

    ¥We are using a Vue scoped slot called item to define how each record (the equivalent of a row in non-grid mode) should look. This allows you total freedom.

  • 我们使用多选功能。

    ¥We are using multiple selection.

Grid style with slot



扩展行(Expanding rows)

¥Expanding rows

警告

如果你从数据中的一行生成多个 QTr,请在 QTr 上添加唯一的(不同的)key

¥Add unique (distinct) key on QTr if you generate more than one QTr from a row in data.

Internal expansion model



也可以使用外部扩展模型:

¥An external expansion model can also be used:

External expansion model



如果你在 QTable 中使用虚拟滚动,你应该知道有两个实用 CSS 类可以控制 VirtualScroll 的大小计算:

¥If you are using virtual scroll with QTable, you should know that there are 2 utility CSS classes that control VirtualScroll size calculation:

  • 在 VirtualScroll 渲染的元素上使用 q-virtual-scroll--with-prev 类,以指示该元素应与前一个元素分组(主要用例是从同一行数据生成的多个表格行)。

    ¥Use q-virtual-scroll--with-prev class on an element rendered by the VirtualScroll to indicate that the element should be grouped with the previous one (main use case is for multiple table rows generated from the same row of data).

  • 在 VirtualScroll 渲染的元素上使用 q-virtual-scroll--skip 类,以指示在大小计算中应忽略该元素的大小。

    ¥Use q-virtual-scroll--skip class on an element rendered by the VirtualScroll to indicate that the element’s size should be ignored in size calculations.

Virtual scroll with expansion model



升级前/升级后插槽(Before/after slots)

¥Before/after slots




分页(Pagination)

¥Pagination

提示

pagination 具有名为 rowsNumber 的属性时,这意味着你将配置 Table 以进行服务器端分页(以及排序和过滤)。参见 “服务器端分页、过滤和排序” 部分。

¥When pagination has a property named rowsNumber, then this means that you’ll be configuring Table for server-side pagination (& sorting & filtering). See “Server side pagination, filter and sorting” section.

以下是两个处理分页(以及排序和每页行数)的示例。

¥Below are two examples of handling the pagination (and sorting and rows per page).

第一个例子重点介绍了如何配置初始分页:

¥The first example highlights how to configure the initial pagination:

Initial pagination



第二个示例使用 “v-model:pagination” 指令,因为我们希望随时访问其当前值。以下技术的一个用例是从 QTable 外部控制分页。

¥The second example uses the “v-model:pagination” directive because we want to access its current value at any time. A use-case for the technique below can be to control the pagination from outside of QTable.

Synchronized pagination



分页槽(Pagination slot)

¥Pagination slot

出于学习目的,我们将使用默认控件自定义分页控件,以帮助你开始使用自己的控件。

¥For learning purposes, we will customize the pagination controls with the default controls in order to help you get started with your own.

Pagination slot



加载状态(Loading state)

¥Loading state

Default loading



Custom loading state



自定义顶部(Custom top)

¥Custom top

Custom top with add/remove row



Body 插槽(Body slots)

¥Body slots

以下示例展示了如何使用插槽自定义整行:

¥The example below shows how you can use a slot to customize the entire row:

Body slot



下面,我们使用一个应用于每个 body 单元格的 slot:

¥Below, we use a slot which gets applied to each body cell:

Body-cell slot



我们也可以只自定义一个特定的列。此插槽的语法为 body-cell-[name],其中 [name] 应替换为用作行键的每一行的属性。

¥We can also customize only one particular column only. The syntax for this slot is body-cell-[name], where [name] should be replaced by the property of each row which is used as the row-key.

Body-cell-[name] slot



标题栏位(Header slots)

¥Header slots

以下示例展示了如何使用插槽自定义整个标题行:

¥The example below shows how you can use a slot to customize the entire header row:

Header slot



下面,我们使用一个应用于每个 header 单元格的 slot:

¥Below, we use a slot which gets applied to each header cell:

Header-cell slot



我们也可以只自定义一个特定的标题单元格。此插槽的语法为 header-cell-[name],其中 [name] 应替换为用作行键的每一行的属性。

¥We can also customize only one particular header cell only. The syntax for this slot is header-cell-[name], where [name] should be replaced by the property of each row which is used as the row-key.

Header-cell-[name] slot



无数据(No data)

¥No data

No Data Label



还有一个 “no-data” 作用域插槽(见下文),当过滤器未返回任何结果或表格中没有数据可显示时,你还可以自定义两者的消息。另请在 “搜索” 输入框中输入一些内容。

¥There is also a “no-data” scoped slot (see below) that you can also to customize the messages for both when a filter doesn’t returns any results or the table has no data to display. Also type something into the “Search” input.

No Data Slot



处理底层(Handling bottom layer)

¥Handling bottom layer

有一些属性可用于隐藏底层或其特定部分。你可以在下面试用:

¥There are a few properties that you can use to hide the bottom layer or specific parts of it. You can play with it below:

Hiding bottom layer



自定义排序(Custom sorting)

¥Custom sorting

Custom sorting



响应式表格(Responsive tables)

¥Responsive tables

为了创建响应式表格,我们有两个工具可供使用:densegrid 属性。我们可以将它们与 $q.screen 连接。更多信息:屏幕插件

¥In order to create responsive tables, we have two tools at our disposal: dense and grid properties. We can connect these with $q.screen. More info: Screen Plugin.

下面的第一个示例使用 $q.screen.lt.md(用于启用密集模式),第二个示例使用 $q.screen.xs 启用网格模式,因此请尝试调整浏览器宽度来查看它们的实际效果。

¥First example below uses $q.screen.lt.md (for enabling dense mode) and the second examples uses $q.screen.xs to enable grid mode, so play with browser width to see them in action.

Using dense prop



Using grid prop



服务器端分页、过滤和排序(Server side pagination, filter and sorting)

¥Server side pagination, filter and sorting

当你的数据库包含大量表行时,由于多种原因(内存、UI 渲染性能等),加载所有行显然是不可行的。相反,你可以只加载一个表格页面。每当用户想要导航到另一个表格页面,或者想要按列排序或想要过滤表格时,都会向服务器发送请求以获取部分分页的数据。

¥When your database contains a big number of rows for a Table, obviously it’s not feasible to load them all for multiple reasons (memory, UI rendering performance, …). Instead, you can load only a Table page. Whenever the user wants to navigate to another Table page, or wants to sort by a column or wants to filter the Table, a request is sent to the server to fetch the partially paged data.

  1. 启用此行为的第一步是指定 pagination 属性,该属性必须包含 rowsNumber。QTable 需要知道可用的总行数才能正确渲染分页链接。如果过滤导致 rowsNumber 发生变化,则必须动态修改。

    ¥First step to enable this behavior is to specify pagination prop, which MUST contain rowsNumber. QTable needs to know the total number of rows available in order to correctly render the pagination links. Should filtering cause the rowsNumber to change then it must be modified dynamically.

  2. 第二步是监听 QTable 上的 @request 事件。当页码、排序或筛选条件发生变化,需要从服务器获取数据时,会触发此事件。

    ¥Second step is to listen for @request event on QTable. This event is triggered when data needs to be fetched from the server because either page number or sorting or filtering changed.

  3. 最好也指定 loading 属性,以便通知用户后台进程正在进行中。

    ¥It’s best that you also specify the loading prop in order to notify the user that a background process is in progress.

提示

在以下示例中,已采取步骤模拟对服务器的 Ajax 调用。虽然概念相似,但如果你使用此代码,则需要进行适当的更改以连接到你自己的数据源。

¥In the example below, steps have been taken to emulate an ajax call to a server. While the concepts are similar, if you use this code you will need to make the appropriate changes to connect to your own data source.

Synchronizing with server



导出数据(Exporting data)

¥Exporting data

下面是一个使用 exportFile Quasar 实用程序进行简单 csv 编码然后导出表格数据的示例。浏览器应该会触发文件下载。为了获得更专业的编码方法,我们建议使用 csv-parsecsv-stringify 包。

¥Below is an example of a naive csv encoding and then exporting table data by using the exportFile Quasar util. The browser should trigger a file download. For a more professional approach in regards to encoding we do recommend using csv-parse and csv-stringify packages.

提示

如果你想导出用户过滤和排序后的数据,还可以使用 QTable 的 filteredSortedRows 内部计算属性。

¥You could also make use of the filteredSortedRows internal computed property of QTable should you want to export the user filtered + sorted data.

Export to csv



键盘导航(Keyboard navigation)

¥Keyboard navigation

以下是使用选定行在表格中进行键盘导航的示例。使用 ArrowUpArrowDownPageUpPageDownHomeEnd 键进行导航。

¥Below is an example of keyboard navigation in the table using selected row. Use ArrowUp, ArrowDown, PageUp, PageDown, Home and End keys to navigate.

Keyboard navigation