BasicTable 表格组件

Data Table 组件进行封装

如果文档内没有,可以尝试在在线示例内寻找

基础使用

  1. <template>
  2. <n-card :bordered="false" class="proCard">
  3. <BasicTable
  4. title="表格列表"
  5. titleTooltip="这是一个提示"
  6. :columns="columns"
  7. :request="loadDataTable"
  8. :row-key="(row) => row.id"
  9. ref="actionRef"
  10. :actionColumn="actionColumn"
  11. @update:checked-row-keys="onCheckedRow"
  12. >
  13. <template #toolbar>
  14. <n-button type="primary" @click="reloadTable">刷新数据</n-button>
  15. </template>
  16. </BasicTable>
  17. </n-card>
  18. </template>
  19. <script lang="ts">
  20. import { defineComponent, reactive, toRefs, ref, h } from 'vue';
  21. import { BasicTable, TableAction } from '@/components/Table';
  22. import { getTableList } from '@/api/table/list';
  23. import { columns } from './basicColumns';
  24. import { useDialog, useMessage } from 'naive-ui';
  25. export default defineComponent({
  26. components: { BasicTable },
  27. setup() {
  28. const message = useMessage();
  29. const dialog = useDialog();
  30. const actionRef = ref();
  31. const state = reactive({
  32. params: {
  33. pageSize: 5,
  34. name: 'xiaoMa',
  35. },
  36. actionColumn: {
  37. width: 150,
  38. title: '操作',
  39. dataIndex: 'action',
  40. fixed: 'right',
  41. align: 'center',
  42. render(record) {
  43. return h(TableAction, {
  44. style: 'button',
  45. actions: createActions(record),
  46. });
  47. },
  48. },
  49. });
  50. function createActions(record) {
  51. return [
  52. {
  53. label: '删除',
  54. icon: 'ic:outline-delete-outline',
  55. onClick: handleDelete.bind(null, record),
  56. // 根据业务控制是否显示 isShow 和 auth 是并且关系
  57. ifShow: () => {
  58. return true;
  59. },
  60. // 根据权限控制是否显示: 有权限,会显示,支持多个
  61. auth: ['basic_list'],
  62. },
  63. {
  64. label: '编辑',
  65. onClick: handleEdit.bind(null, record),
  66. ifShow: () => {
  67. return true;
  68. },
  69. auth: ['basic_list'],
  70. },
  71. ];
  72. }
  73. const loadDataTable = async (params) => {
  74. const data = await getTableList(params);
  75. return data;
  76. };
  77. function onCheckedRow(rowKeys) {
  78. console.log(rowKeys);
  79. }
  80. function reloadTable() {
  81. actionRef.value.reload();
  82. }
  83. function handleDelete(record) {
  84. console.log(record);
  85. dialog.info({
  86. title: '提示',
  87. content: `您想删除${record.name}`,
  88. positiveText: '确定',
  89. negativeText: '取消',
  90. onPositiveClick: () => {
  91. message.success('删除成功');
  92. },
  93. onNegativeClick: () => {},
  94. });
  95. }
  96. function handleEdit(record) {
  97. console.log(record);
  98. message.success('您点击了编辑按钮');
  99. }
  100. return {
  101. ...toRefs(state),
  102. columns,
  103. actionRef,
  104. loadDataTable,
  105. onCheckedRow,
  106. reloadTable,
  107. };
  108. },
  109. });
  110. </script>

编辑单元格

  1. <template>
  2. <n-card :bordered="false" class="proCard">
  3. <BasicTable
  4. title="表格列表"
  5. titleTooltip="这是一个提示"
  6. :columns="columns"
  7. :request="loadDataTable"
  8. :row-key="(row) => row.id"
  9. ref="actionRef"
  10. :actionColumn="actionColumn"
  11. @edit-end="editEnd"
  12. @edit-change="onEditChange"
  13. @update:checked-row-keys="onCheckedRow"
  14. >
  15. <template #toolbar>
  16. <n-button type="primary" @click="reloadTable">刷新数据</n-button>
  17. </template>
  18. </BasicTable>
  19. </n-card>
  20. </template>
  21. <script lang="ts">
  22. import { defineComponent, reactive, toRefs, ref, h } from 'vue';
  23. import { BasicTable, TableAction } from '@/components/Table';
  24. import { getTableList } from '@/api/table/list';
  25. import { columns } from './CellColumns';
  26. export default defineComponent({
  27. components: { BasicTable },
  28. setup() {
  29. const actionRef = ref();
  30. const currentEditKeyRef = ref('');
  31. const state = reactive({
  32. params: {
  33. pageSize: 5,
  34. name: 'xiaoMa',
  35. },
  36. actionColumn: {
  37. width: 150,
  38. title: '操作',
  39. dataIndex: 'action',
  40. fixed: 'right',
  41. align: 'center',
  42. render(record) {
  43. return h(TableAction, {
  44. style: 'button',
  45. actions: createActions(record),
  46. });
  47. },
  48. },
  49. });
  50. function handleEdit(record) {
  51. currentEditKeyRef.value = record.key;
  52. record.onEdit?.(true);
  53. }
  54. function handleCancel(record: EditRecordRow) {
  55. currentEditKeyRef.value = '';
  56. record.onEdit?.(false, false);
  57. }
  58. function onEditChange({ column, value, record }) {
  59. if (column.dataIndex === 'id') {
  60. record.editValueRefs.name4.value = `${value}`;
  61. }
  62. console.log(column, value, record);
  63. }
  64. async function handleSave(record: EditRecordRow) {
  65. const pass = await record.onEdit?.(false, true);
  66. if (pass) {
  67. currentEditKeyRef.value = '';
  68. }
  69. }
  70. function createActions(record) {
  71. if (!record.editable) {
  72. return [
  73. {
  74. label: '编辑',
  75. onClick: handleEdit.bind(null, record),
  76. },
  77. ];
  78. } else {
  79. return [
  80. {
  81. label: '保存',
  82. onClick: handleSave.bind(null, record),
  83. },
  84. {
  85. label: '取消',
  86. onClick: handleCancel.bind(null, record),
  87. },
  88. ];
  89. }
  90. }
  91. const loadDataTable = async (params) => {
  92. const data = await getTableList(params);
  93. return data;
  94. };
  95. function onCheckedRow(rowKeys) {
  96. console.log(rowKeys);
  97. }
  98. function reloadTable() {
  99. console.log(actionRef.value);
  100. actionRef.value.reload();
  101. }
  102. function editEnd({ record, index, key, value }) {
  103. console.log(value);
  104. }
  105. return {
  106. ...toRefs(state),
  107. columns,
  108. actionRef,
  109. loadDataTable,
  110. onCheckedRow,
  111. reloadTable,
  112. editEnd,
  113. onEditChange,
  114. };
  115. },
  116. });
  117. </script>

编辑整行

  1. <template>
  2. <n-card :bordered="false" class="proCard">
  3. <BasicTable
  4. title="表格列表"
  5. titleTooltip="这是一个提示"
  6. :columns="columns"
  7. :request="loadDataTable"
  8. :row-key="(row) => row.id"
  9. ref="actionRef"
  10. :actionColumn="actionColumn"
  11. @edit-end="editEnd"
  12. @edit-change="onEditChange"
  13. @update:checked-row-keys="onCheckedRow"
  14. >
  15. <template #toolbar>
  16. <n-button type="primary" @click="reloadTable">刷新数据</n-button>
  17. </template>
  18. </BasicTable>
  19. </n-card>
  20. </template>
  21. <script lang="ts">
  22. import { defineComponent, reactive, toRefs, ref, h } from 'vue';
  23. import { BasicTable, TableAction } from '@/components/Table';
  24. import { getTableList } from '@/api/table/list';
  25. import { columns } from './rowColumns';
  26. export default defineComponent({
  27. components: { BasicTable },
  28. setup() {
  29. const actionRef = ref();
  30. const currentEditKeyRef = ref('');
  31. const state = reactive({
  32. params: {
  33. pageSize: 5,
  34. name: 'xiaoMa',
  35. },
  36. actionColumn: {
  37. width: 150,
  38. title: '操作',
  39. key: 'action',
  40. fixed: 'right',
  41. align: 'center',
  42. render(record) {
  43. return h(TableAction, {
  44. style: 'button',
  45. actions: createActions(record),
  46. });
  47. },
  48. },
  49. });
  50. function handleEdit(record) {
  51. currentEditKeyRef.value = record.key;
  52. record.onEdit?.(true);
  53. }
  54. function handleCancel(record: EditRecordRow) {
  55. currentEditKeyRef.value = '';
  56. record.onEdit?.(false, false);
  57. }
  58. function onEditChange({ column, value, record }) {
  59. if (column.dataIndex === 'id') {
  60. record.editValueRefs.name4.value = `${value}`;
  61. }
  62. console.log(column, value, record);
  63. }
  64. async function handleSave(record: EditRecordRow) {
  65. const pass = await record.onEdit?.(false, true);
  66. if (pass) {
  67. currentEditKeyRef.value = '';
  68. }
  69. }
  70. function createActions(record) {
  71. if (!record.editable) {
  72. return [
  73. {
  74. label: '编辑',
  75. onClick: handleEdit.bind(null, record),
  76. },
  77. ];
  78. } else {
  79. return [
  80. {
  81. label: '保存',
  82. onClick: handleSave.bind(null, record),
  83. },
  84. {
  85. label: '取消',
  86. onClick: handleCancel.bind(null, record),
  87. },
  88. ];
  89. }
  90. }
  91. const loadDataTable = async (params) => {
  92. const data = await getTableList(params);
  93. return data;
  94. };
  95. function onCheckedRow(rowKeys) {
  96. console.log(rowKeys);
  97. }
  98. function reloadTable() {
  99. console.log(actionRef.value);
  100. actionRef.value.reload();
  101. }
  102. function editEnd({ record, index, key, value }) {
  103. console.log(value);
  104. }
  105. return {
  106. ...toRefs(state),
  107. columns,
  108. actionRef,
  109. loadDataTable,
  110. onCheckedRow,
  111. reloadTable,
  112. editEnd,
  113. onEditChange,
  114. };
  115. },
  116. });
  117. </script>

支持编辑组件

  1. import {
  2. NInput,
  3. NSelect,
  4. NCheckbox,
  5. NInputNumber,
  6. NSwitch,
  7. NDatePicker,
  8. NTimePicker,
  9. } from 'naive-ui';

Props

::: tip 温馨提醒

  • 除以下参数外,官方文档内的 props 也都支持,具体可以参考 Data Table :::
属性 类型 默认值 可选值 说明 版本
title string null - 表格标题
titleTooltip string null - 表格标题右侧温馨提醒
dataSource any[] - - 表格数据(非 request 加载情况,直接传数组即可)
request function - - 请求接口,如数据不需要二次处理,可以直接将src/api内的函数直接传入
pagination any - - 分页信息配置,为 false 不显示分页
canResize boolean true - 是否可以自适应高度
resizeHeightOffset number 0 - 表格自适应高度计算结果会减去这个值
actionColumn object - - 操作列按钮,用render 配合TableAction实现,参考以上基础表格示例

column

除 参考官方 Column 配置外,扩展以下参数

属性 类型 默认值 可选值 说明
helpMessage string|string[] - - 列头右侧帮助文本
edit boolean - - 是否开启单元格编辑
editRow boolean - - 是否开启行编辑
editable boolean false - 是否处于编辑状态
editComponent ComponentType Input - 编辑组件
editComponentProps any - - 对应编辑组件的 props
editRule ((text: string, record: Recordable) => Promise<string>) - - 对应编辑组件的表单校验
editValueMap (value: any) => string - - 对应单元格值枚举
onEditRow ()=>void - - 触发行编辑
auth RoleEnumRoleEnum[]stringstring[] - - 根据权限编码来控制当前列是否显示
ifShow boolean | ((action: ActionItem) => boolean) - - 根据业务状态来控制当前列是否显示

tableAction

  1. {
  2. // 按钮列表
  3. actions: Array;
  4. // 按钮风格 可选 `button`, `text`
  5. style?: String;
  6. // 更多按钮列表
  7. dropDownActions?: Array;
  8. // 更多按钮选择之后回调事件
  9. select?: Function;
  10. }

tableAction.actions

  1. {
  2. //按钮点击
  3. onClick?: Fn;
  4. //按钮文字
  5. label?: string;
  6. //主题
  7. color?: 'success' | 'error' | 'warning';
  8. //图标,暂未实现
  9. icon?: string;
  10. //禁用
  11. disabled?: boolean;
  12. // 权限编码控制是否显示
  13. auth?: RoleEnum | RoleEnum[] | string | string[];
  14. // 业务控制是否显示
  15. ifShow?: boolean | ((action: ActionItem) => boolean);
  16. }

事件

::: tip 温馨提醒

除以下事件外,官方文档内的 event 也都支持,具体可以参考 Data Table

:::

事件 回调参数 说明
fetch-success Function({items,total}) 接口请求成功后触发
fetch-error Function(error) 错误信息
edit-end Function({record, index, key, value}) 单元格编辑完成触发
edit-cancel Function({record, index, key, value}) 单元格取消编辑触发
edit-row-end Function() 行编辑结束触发
edit-change Function({column,value,record}) 单元格编辑组件的 value 发生变化时触发

::: tip edit-change 说明

对于 edit-change 事件,record 中的 editValueRefs 装载了当前行的所有编辑组件(如果有的话)的值的 ref 对象,可用于处理同一行中的编辑组件的联动。请看下面的例子

:::

  1. function onEditChange({ column, record }) {
  2. // 当同一行的单价或者数量发生变化时,更新合计金额(三个数据均为当前行编辑组件的值)
  3. if (column.dataIndex === 'qty' || column.dataIndex === 'price') {
  4. const { editValueRefs: { total, qty, price } } = record;
  5. total.value = unref(qty) * unref(price);
  6. }
  7. }

Slots

::: tip 温馨提醒

除以下参数外,官方文档内的 slot 也都支持,Data Table

:::

名称 说明 版本
tableTitle 表格顶部左侧区域
toolbar 表格顶部右侧区域