naive-ui-table文档
版本变更日志
2.0.0
更新日期:2024-10-17
更新点:
- 修复表格作用域插槽格式:由原先的
<template #operation="row, index">
换成标准格式<template #operation="{row, index}">
; - 更换拖拽插件:由
vuedraggable
换成了vue-draggable-plus
; - 更换列设置功能和样式:由抽屉换成弹出信息,删除列固定功能;
- 兼容多级表头的属性添加(ellipsis省略号、列slot);
- 修复表格顶部无内容时的样式冗余。
1.0.x
功能点:
- 表格作用域插槽格式为:
<template #operation="row, index">
; - 列设置功能:右侧抽屉弹出,支持列固定、列拖拽排序、列隐藏。
介绍
naive-ui-table是基于naive-ui的table组件封装的组件,主要区别是内置了很多常用功能,但配置非常简单,更能满足多种情况的开发需求。且支持naive-ui
的data-table
的所有属性。
功能如下:
- 表格列
columns
配置与naive-ui
一致(增加了vif
),且自定义列增加了插槽配置; - 自带分页:若接口可以分页查询,则分页配置与接口相结合;若接口不分页,则由表格自动分页。
- 自带搜索:只需要传入
search-props
配置,即可实现搜索功能; - 自带列设置:可设置列显隐、拖拽排序等;
- 表格高度自适应,避免数据过多时页面出现滚动条。
提示
naive-ui-table
支持naive-ui
的data-table
的所有属性。
安装、使用
# 安装
pnpm add naive-ui-table
# 更新
pnpm update naive-ui-table
全局注册
import { createApp } from 'vue'
import NaiveUiTable from 'naive-ui-table'
import 'naive-ui-table/dist/style.css'
const app = createApp(App)
app.use(NaiveUiTable)
局部引入
<template>
<NaiveUiTable></NaiveUiTable>
</template>
<script setup lang="ts">
import { NaiveUiTable } from 'naive-ui-table'
import 'naive-ui-table/dist/style.css'
</script>
基础用法
只需传入两个参数columns
和requestApi
,即可实现异步分页请求数据展示表格。
<template>
<NaiveUiTable :columns="columns" :requestApi="getTableList"></NaiveUiTable>
</template>
<script setup lang="tsx">
import { NaiveUiTable, type TableColumns } from 'naive-ui-table'
const columns: TableColumns = [
{ title: '姓名', key: 'name' },
{ title: '年龄', key: 'age' }
]
// 返回带结果的promise对象
function getTableList(params: any) {
return api(params)
}
</script>
注意
该 columns 配置除了新增vif
外,其余配置与naive-ui
的data-table
的columns
完全一致。具体属性参考naive-ui的columns
是否分页:
- 默认接口是分页接口(
isPageApi: true
),即:- 接口参数包含
current,size
- 接口返回数据格式为
{ current: 1, size: 10, total: 100, records: [...] }
;
- 接口参数包含
- 若接口不分页,需将
isPageApi
设为false
,即:- 接口参数里没有
current,size
- 接口返回数据格式为
[...]
;
- 接口参数里没有
表格列显隐vif
columns.vif
:(boolean | (() => boolean) | Ref<boolean>
)动态显示该列。- 类型为返回布尔值的表达式、函数、ref状态。不传默认显示。
<template>
<NaiveUiTable :columns="columns" :requestApi="getTableList"></NaiveUiTable>
</template>
<script setup lang="tsx">
import { NaiveUiTable, type TableColumns } from 'naive-ui-table'
const sex = ref(true)
const columns: TableColumns = [
{
title: '姓名',
key: 'name',
vif: true
},
{
title: '年龄',
key: 'age',
vif: () => true
},
{
title: '性别',
key: 'sex',
vif: sex
}
]
function getTableList(params: any) {
return api(params)
}
</script>
表格左上角-Header按钮
tableHeader
插槽,用于自定义表格左上角的内容,例如标题、按钮等。
<template>
<NaiveUiTable :columns="columns" :requestApi="getTableList">
<template #tableHeader>
<n-button type="primary">新增</n-button>
<n-button>导出</n-button>
</template>
</NaiveUiTable>
</template>
<script setup lang="tsx">
import { NaiveUiTable, type TableColumns } from 'naive-ui-table'
const columns: TableColumns = [
{ title: '姓名', key: 'name' },
{ title: '年龄', key: 'age' }
]
function getTableList(params: any) {
return api(params)
}
</script>
表格右上角-工具按钮
toolButton
属性:控制右上角工具按钮;默认为true
,表示展示全部按钮:
- 【刷新】:刷新当前页数据
- 【密度】:也就是表格的
size
属性 - 【列设置】:列设置弹出信息框,可拖拽改变列的顺序、设置列的显隐
// 是否显示表格功能按钮
toolButton?: ('refresh' | 'size' | 'setting')[] | boolean
若只想展示【刷新】【密度】两个按钮:
<template>
<NaiveUiTable
:columns="columns"
:requestApi="getTableList"
:toolButton="['refresh', 'size']"
>
</NaiveUiTable>
</template>
若不展示所有按钮,则传入空数组[]
或false
:
<template>
<NaiveUiTable
:columns="columns"
:requestApi="getTableList"
:toolButton="false"
>
</NaiveUiTable>
</template>
toolButton
插槽:若要增加内容,通过该插槽可以写入自定义内容
<template>
<NaiveUiTable
:columns="columns"
:requestApi="getTableList"
>
<template #toolButton>
<n-button>其他工具按钮</n-button>
</template>
</NaiveUiTable>
</template>
表格列自定义
方式一:用render
函数
按原来的属性,在columns
里用render
函数自定义列的内容。
<template>
<NaiveUiTable :columns="columns" :requestApi="getTableList"></NaiveUiTable>
</template>
<script setup lang="tsx">
import { NaiveUiTable, type TableColumns } from 'naive-ui-table'
const columns: TableColumns = [
{
title: '姓名',
key: 'name',
render: (row) => <n-tag type="primary">{row.name}</n-tag>
},
{ title: '年龄', key: 'age' }
]
function getTableList(params: any) {
return api(params)
}
</script>
方式二:用插槽
用插槽自定义列,插槽名需与该列的key
保持一致,接收数据对象与render函数的参数一致:row
为每一行数据,index
为索引值。
<template>
<NaiveUiTable :columns="columns" :requestApi="getTableList">
<template #name="{row, index}">
<n-tag type="primary">{{ row.name }}</n-tag>
</template>
</NaiveUiTable>
</template>
<script setup lang="tsx">
import { NaiveUiTable, type TableColumns } from 'naive-ui-table'
const columns: TableColumns = [
{ title: '姓名', key: 'name' },
{ title: '年龄', key: 'age' }
]
function getTableList(params: any) {
return api(params)
}
</script>
表格操作列
操作列的 key 和 插槽名 固定为 operation
。
方式一:用render
函数
按原来的属性,在 columns
的operation
列配置里,用render
函数自定义列。
<template>
<NaiveUiTable :columns="columns" :requestApi="getTableList"></NaiveUiTable>
</template>
<script setup lang="tsx">
import { NaiveUiTable, type TableColumns } from 'naive-ui-table'
const columns: TableColumns = [
{ title: '姓名', key: 'name' },
{ title: '年龄', key: 'age' },
{
title: '操作',
key: 'operation',
fixed: 'right',
align: 'center',
width: 330,
render(row) {
return (
<NSpace>
<NButton type="primary" ghost onClick={() => fun('查看', row)}>查看</NButton>
<NButton type="primary" ghost onClick={() => fun('编辑', row)}>编辑</NButton>
<NButton type="error" ghost onClick={() => fun('删除', row)}>删除</NButton>
</NSpace>
)
}
}
]
function fun(type, row) {
console.log(type, row)
}
function getTableList(params: any) {
return api(params)
}
</script>
方式二:用插槽operation
也可用插槽operation
自定义列;接收数据对象中,row
为每一行数据,index
为索引值。
<template>
<NaiveUiTable :columns="columns" :requestApi="getTableList">
<!-- 表格操作列 -->
<template #operation="{row, index}">
<n-button type="primary" ghost @click="fun('查看', row)">查看</n-button>
<n-button type="primary" ghost @click="fun('编辑', row)">编辑</n-button>
<n-button type="error" ghost @click="fun('删除', row)">删除</n-button>
</template>
</NaiveUiTable>
</template>
<script setup lang="tsx">
import { NaiveUiTable, type TableColumns } from 'naive-ui-table'
const columns: TableColumns = [
{ title: '姓名', key: 'name'},
{ title: '年龄', key: 'age' },
{ title: '操作', key: 'operation', fixed: 'right', align: 'center', width: 330 }
]
function fun(type, row) {
console.log(type, row)
}
function getTableList(params: any) {
return api(params)
}
</script>
查询表单
传入search-props
配置将开启查询表单:
- 查询表单调用
naive-ui-form
组件,search-props
配置与useForm
的参数一致; - 查询、重置功能已内置在表格组件里,无需额外传输;
- 查询参数,已经与表格接口的参数合并;如需额外处理,可在
requestApi
接口请求之前处理。
<template>
<NaiveUiTable
:columns="columns"
:requestApi="getTableList"
:search-props="search"
></NaiveUiTable>
</template>
<script setup lang="ts">
import { NaiveUiTable } from 'naive-ui-table'
import type { TableColumns, FormProps } from 'naive-ui-table'
const columns: TableColumns = [
{ title: '姓名', key: 'name' },
{ title: '年龄', key: 'age' },
{ title: '地址', key: 'address' }
]
// 搜索栏配置
const search: FormProps = {
schemas: [
{
label: '姓名',
field: 'name',
type: 'input',
},
{
label: '年龄',
field: 'age',
type: 'input-number',
}
]
}
function getTableList(params: any) {
return api(params)
}
</script>
组件内部:search-props
对象将全部传递给useForm
const [register] = useForm(props.searchProps)
查询表单-插槽
- 查询表单也可以使用插槽,用法与
naive-fi-form
组件的插槽完全一致,自行参考naive-fi-form
的插槽用法。
注意:
slot插槽名不能与columns
的key
重复。否则该插槽会同时作为表格的自定义列的内容。
<template>
<NaiveUiTable
:columns="columns"
:requestApi="getTableList"
:search-props="search"
>
<!-- 查询表单插槽 -->
<template #username="{ formValue, field }">
<input
v-model="formValue[field]"
type="text"
placeholder="这是插槽"
style="border: 1px solid #ccc"
/>
</template>
</NaiveUiTable>
</template>
<script setup lang="tsx">
import type { TableColumns, FormProps } from 'naive-ui-table'
const columns: TableColumns = [
{ title: '姓名', key: 'name' },
{ title: '年龄', key: 'age' },
{ title: '地址', key: 'address' }
]
// 搜索栏配置
const search: FormProps = {
schemas: [
{
label: '姓名',
field: 'name',
type: 'slot',
slot: 'username'
},
{
label: '年龄',
field: 'age',
type: 'input-number'
}
]
}
function getTableList(params: any) {
return api(params)
}
</script>
获取勾选数据
方式一:@update:checked-row-keys
回调
传入@update:checked-row-keys
回调函数,可实时获取到已勾选的keys, rows, meta
。
注意
- 该
@update:checked-row-keys
与naive-ui的@update:checked-row-keys
完全一致; - 默认的 row-key 是
(row) => row.id
,可自行传入row-key
属性将其覆盖。
<template>
<NaiveUiTable
:columns="columns"
:requestApi="getTableList"
@update:checked-row-keys="handleCheck"
></NaiveUiTable>
</template>
<script setup lang="tsx">
import { NaiveUiTable, type TableColumns } from 'naive-ui-table'
const columns: TableColumns = [
{ type: 'selection', multiple: true }, // 勾选列
{ title: '姓名', key: 'name' },
{ title: '年龄', key: 'age' }
]
// 勾选回调
function handleCheck(keys: Array<string | number>) {
console.log('param: ', keys)
}
function getTableList(params: any) {
return api(params)
}
</script>
方式二:getCheckValue
方法
<template>
<NaiveUiTable
:ref="tableRef"
:columns="columns"
:requestApi="getTableList"
></NaiveUiTable>
<button @click="func">获取勾选的数据</button>
</template>
<script setup lang="tsx">
import type { TableColumns, TableInstance } from 'naive-ui-table'
// 表格配置项
const columns: TableColumns = [
{ type: 'selection', multiple: true }, // 勾选列
{ title: '姓名', key: 'name' },
{ title: '年龄', key: 'age' }
]
function getTableList(params: any) {
return api(params)
}
const tableRef = ref<TableInstance>()
// 获取勾选的数据信息
function func() {
const checkInfo = tableRef.value?.getCheckValue()
}
</script>
表格高度自适应
- 当窗口size改变时,会自动调整表格高度。避免页面出现滚动条。
- 前提:该表格组件为页面的最底部的组件。
- 若表格下面有内容要展示,则需要传入该内容的高度,表格底部就会留出相应的空间。
// 表格底部留白距离。非必传(默认:25)
resizeHeightOffset?: number
<template>
<NaiveUiTable
:columns="columns"
:requestApi="getTableList"
:resizeHeightOffset="100"
>
</NaiveUiTable>
</template>
若需要固定高度,不需要自适应,则自行传入maxHeight
将其覆盖
<template>
<NaiveUiTable
:columns="columns"
:requestApi="getTableList"
:maxHeight="500"
>
</NaiveUiTable>
</template>
增加接口请求的参数
方式一:传入initParams
对象
- 要额外增加接口请求的参数,可传入
initParams
对象,该对象将会与接口请求的参数合并。
<template>
<NaiveUiTable
:columns="columns"
:requestApi="getTableList"
:initParams="{
type: 1,
id: 'xxxxxx'
}"
>
</NaiveUiTable>
</template>
<script setup lang="tsx">
import { NaiveUiTable, type TableColumns } from 'naive-ui-table'
const columns: TableColumns = [
{ title: '姓名', key: 'name' },
{ title: '年龄', key: 'age' }
]
function getTableList(params: any) {
console.log(params) // {type: 1, id: 'xxxxxx', current: 1, size: 10}
return api(params)
}
</script>
方式二:在requestApi
接口请求之前处理
- 在
requestApi
接口请求之前,可在params
对象上增加额外的参数。
<template>
<NaiveUiTable :columns="columns" :requestApi="getTableList"> </NaiveUiTable>
</template>
<script setup lang="tsx">
import { NaiveUiTable, type TableColumns } from 'naive-ui-table'
const columns: TableColumns = [
{ title: '姓名', key: 'name' },
{ title: '年龄', key: 'age' }
]
function getTableList(params: any) {
params.type = 1
params.id = 'xxxxxx'
return api(params)
}
/* 参数:{current: 1, size: 10, type: 1, id: 'xxxxxx'} */
</script>
数据处理回调dataCallback
- 该函数接收接口返回的原始数据,返回目标表格数据。
- 如果数据格式不符合要求、或者接口请求后立马需要执行某些逻辑,有两种解决方式:
- 方式一:在
requestApi
接口请求里处理; - 方式二:在
dataCallback
回调函数里处理。
- 方式一:在
<template>
<NaiveUiTable
:columns="columns"
:requestApi="getTableList"
:dataCallback="dataCallback"
>
</NaiveUiTable>
</template>
<script setup lang="tsx">
import { NaiveUiTable, type TableColumns } from 'naive-ui-table'
const columns: TableColumns = [
{ title: '姓名', key: 'name' },
{ title: '年龄', key: 'age' }
]
// 方式一:接口请求里。返回正确的表格数据,或增加其他逻辑
function getTableList(params: any) {
return api(params)
}
// 方式二:dataCallback。返回正确的表格数据,或增加其他逻辑
function dataCallback(data) {
data.records = data.records.map((item, index) => {
item.name = item.name + index
return item
})
return data
}
</script>
返回正确的数据格式:
- 若接口为分页接口,则需要返回
{ current: 1, size: 10, total: 100, records: [...] }
格式的数据; - 若接口为非分页接口,则直接返回
[...]
表格数据。
Props
- 必传项只有
columns
;columns
配置除vif
外,其余配置与naive-ui的columns
完全一致,具体配置参考naive-ui的table组件 - 自定义属性如下:
属性 | 类型 | 描述 | 必传 | 默认值 |
---|---|---|---|---|
columns | DataTableColumns | 表格列配置,除vif 外,与naive-ui的完全一致 | 是 | - |
requestApi | (params: any) => Promise<any> | 请求接口,返回带结果的Promise | 否 | - |
search-props | FormProps | 顶部查询表单配置 | 否 | - |
requestAuto | boolean | 是否初始化自动请求接口 | 否 | true |
isPageApi | boolean | 接口是否为分页接口(为true,接口参数里添加分页参数,且分页变化会重新查询表格数据) | 否 | true |
initParams | object | 额外的请求接口的参数 | 否 | - |
dataCallback | (data: object) => object | 接收接口返回的原始数据,返回目标表格数据。(数据格式不符合要求时使用) | 否 | - |
requestError | (error: Error) => void | 请求接口出错时回调 | 否 | - |
toolButton | ('refresh' | 'size' | 'setting')[] | boolean | 是否显示工具栏按钮 | 否 | true |
resizeHeightOffset | number | 表格高度自适应变化时,底部留白距离 | 否 | 25 |
showOrderColumn | boolean | 是否显示序号列 | 否 | false |
- 其余属性:支持naive-ui的
data-table
组件的全部属性。组件内部已经对data-table
内置了以下属性,均可传入将其覆盖:
内置属性 | 描述 |
---|---|
data | 表格数据。内部由 requestApi 请求接口返回。传入可覆盖 |
loading | loading状态。内部跟随接口请求而变化。传入可覆盖 |
pagination | 表格分页配置。接口为分页接口时,页码与接口相结合;反之由表格内部自动分页。传入可覆盖 |
remote | 分页是否异步。接口为分页接口时,值为true,反之为false。传入可覆盖 |
row-key | 行key。内部该值为:(row) => row.id 。传入可覆盖 |
max-height | 最大高度。内部已通过计算得出自适应的最大高度。传入可覆盖 |
scroll-x | 横向宽度。内部已根据columns计算出横向宽度。传入可覆盖 |
size | 表格尺寸。默认值为'medium' ,可点击【工具栏-密度】切换。传入可覆盖 |
single-line | 列分割线。内部该值为true。传入可覆盖 |
... | ......支持传入naive-ui的 data-table 组件的全部属性 |
Methods
通过ref调用以下方法:
名称 | 类型 | 说明 |
---|---|---|
refresh | () => void | 刷新表格数据 |
resetState | () => void | 清空重置表格数据 |
openDrawer | (bool: boolean) => void | 打开列设置抽屉 |
clearCheck | () => void | 清除选中 |
setLoading | (bool: boolean) => void | 设置表格loading |
getTableValue | () => any[] | 获取表格数据 |
getPageValue | () => { current: number, size: number, total: number } | 获取分页数据 |
getCheckValue | () => { keys: DataTableRowKey[]; rows: object[] } | 获取勾选数据 |
reset | () => void | 搜索表单:手动调用重置按钮 |
getValue | () => Recordable | 搜索表单:获取值 |
setValue | (value: Recordable) => void | 搜索表单:设置值 |
getFieldValue | (field: string) => any | 搜索表单:获取指定字段的值 |
States
通过ref调用以下状态:
名称 | 类型 | 说明 |
---|---|---|
basicForm | FormInstance | 查询表单组件BasicForm 的ref实例 |
tableRef | DataTableInst | naive-ui 的n-data-table 组件的ref实例 |
tableColumns | DataTableColumns | 最终传入n-data-table 组件的columns属性 |
height | number | 最终传入n-data-table 组件的maxHeight |
scrollWidth | number | 最终传入n-data-table 组件的scrollX |
Slots
名称 | 参数 | 说明 |
---|---|---|
tableHeader | () | 表格左上角的内容展示 |
toolButton | () | 表格右上角的内容展示 |
operation | ({ row: object, index: number }) | 表格操作列的内容展示 |
[columns.key] | ({ row: object, index: number }) | 表格[columns.key]列的自定义内容 |
[schemas.slot] | ({ formValue: object, field: string }) | 表单[schemas.slot]的自定义内容 |
TS类型
TableColumns:
import type { TableColumns } from 'naive-ui-table'
const columns: TableColumns<any> = [{ title: '姓名', key: 'name' }]
TableInstance:
import type { TableInstance } from 'naive-ui-table'
const tableRef = ref<TableInstance>()
其他:来自naive-ui-form
import type { FormProps, FormInstance } from 'naive-ui-table'
const search: FormProps = {
schemas: [
{
label: '关键词',
field: 'name',
type: 'input'
}
]
}
const formRef = ref<FormInstance>()