Skip to content
On this page

BasicTable 表格组件

Data Table 组件进行封装

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

基础使用

vue
<template>
    <n-card :bordered="false" class="proCard">
        <BasicTable
            title="表格列表"
            titleTooltip="这是一个提示"
            :columns="columns"
            :request="loadDataTable"
            :row-key="(row) => row.id"
            ref="actionRef"
            :actionColumn="actionColumn"
            @update:checked-row-keys="onCheckedRow"
        >
            <template #toolbar>
                <n-button type="primary" @click="reloadTable">刷新数据</n-button>
            </template>
        </BasicTable>
    </n-card>
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs, ref, h } from 'vue';
import { BasicTable, TableAction } from '@/components/Table';
import { getTableList } from '@/api/table/list';
import { columns } from './basicColumns';
import { useDialog, useMessage } from 'naive-ui';
export default defineComponent({
    components: { BasicTable },
    setup() {
        const message = useMessage();
        const dialog = useDialog();
        const actionRef = ref();
        const state = reactive({
            params: {
                pageSize: 5,
                name: 'xiaoMa',
            },
            actionColumn: {
                width: 150,
                title: '操作',
                dataIndex: 'action',
                fixed: 'right',
                align: 'center',
                render(record) {
                    return h(TableAction, {
                        style: 'button',
                        actions: createActions(record),
                    });
                },
            },
        });

        function createActions(record) {
            return [
                {
                    label: '删除',
                    icon: 'ic:outline-delete-outline',
                    onClick: handleDelete.bind(null, record),
                    // 根据业务控制是否显示 isShow 和 auth 是并且关系
                    ifShow: () => {
                        return true;
                    },
                    // 根据权限控制是否显示: 有权限,会显示,支持多个
                    auth: ['basic_list'],
                },
                {
                    label: '编辑',
                    onClick: handleEdit.bind(null, record),
                    ifShow: () => {
                        return true;
                    },
                    auth: ['basic_list'],
                },
            ];
        }

        const loadDataTable = async (params) => {
            const data = await getTableList(params);
            return data;
        };

        function onCheckedRow(rowKeys) {
            console.log(rowKeys);
        }

        function reloadTable() {
            actionRef.value.reload();
        }

        function handleDelete(record) {
            console.log(record);
            dialog.info({
                title: '提示',
                content: `您想删除${record.name}`,
                positiveText: '确定',
                negativeText: '取消',
                onPositiveClick: () => {
                    message.success('删除成功');
                },
                onNegativeClick: () => {},
            });
        }

        function handleEdit(record) {
            console.log(record);
            message.success('您点击了编辑按钮');
        }

        return {
            ...toRefs(state),
            columns,
            actionRef,
            loadDataTable,
            onCheckedRow,
            reloadTable,
        };
    },
});
</script>

编辑单元格

vue
<template>
  <n-card :bordered="false" class="proCard">
    <BasicTable
      title="表格列表"
      titleTooltip="这是一个提示"
      :columns="columns"
      :request="loadDataTable"
      :row-key="(row) => row.id"
      ref="actionRef"
      :actionColumn="actionColumn"
      @edit-end="editEnd"
      @edit-change="onEditChange"
      @update:checked-row-keys="onCheckedRow"
    >
      <template #toolbar>
        <n-button type="primary" @click="reloadTable">刷新数据</n-button>
      </template>
    </BasicTable>
  </n-card>
</template>
<script lang="ts">
  import { defineComponent, reactive, toRefs, ref, h } from 'vue';
  import { BasicTable, TableAction } from '@/components/Table';
  import { getTableList } from '@/api/table/list';
  import { columns } from './CellColumns';
  export default defineComponent({
    components: { BasicTable },
    setup() {
      const actionRef = ref();
      const currentEditKeyRef = ref('');
      const state = reactive({
        params: {
          pageSize: 5,
          name: 'xiaoMa',
        },
        actionColumn: {
          width: 150,
          title: '操作',
          dataIndex: 'action',
          fixed: 'right',
          align: 'center',
          render(record) {
            return h(TableAction, {
              style: 'button',
              actions: createActions(record),
            });
          },
        },
      });

      function handleEdit(record) {
        currentEditKeyRef.value = record.key;
        record.onEdit?.(true);
      }

      function handleCancel(record: EditRecordRow) {
        currentEditKeyRef.value = '';
        record.onEdit?.(false, false);
      }

      function onEditChange({ column, value, record }) {
        if (column.dataIndex === 'id') {
          record.editValueRefs.name4.value = `${value}`;
        }
        console.log(column, value, record);
      }

      async function handleSave(record: EditRecordRow) {
        const pass = await record.onEdit?.(false, true);
        if (pass) {
          currentEditKeyRef.value = '';
        }
      }

      function createActions(record) {
        if (!record.editable) {
          return [
            {
              label: '编辑',
              onClick: handleEdit.bind(null, record),
            },
          ];
        } else {
          return [
            {
              label: '保存',
              onClick: handleSave.bind(null, record),
            },
            {
              label: '取消',
              onClick: handleCancel.bind(null, record),
            },
          ];
        }
      }

      const loadDataTable = async (params) => {
        const data = await getTableList(params);
        return data;
      };

      function onCheckedRow(rowKeys) {
        console.log(rowKeys);
      }

      function reloadTable() {
        console.log(actionRef.value);
        actionRef.value.reload();
      }

      function editEnd({ record, index, key, value }) {
        console.log(value);
      }

      return {
        ...toRefs(state),
        columns,
        actionRef,
        loadDataTable,
        onCheckedRow,
        reloadTable,
        editEnd,
        onEditChange,
      };
    },
  });
</script>

编辑整行

vue
<template>
  <n-card :bordered="false" class="proCard">
    <BasicTable
      title="表格列表"
      titleTooltip="这是一个提示"
      :columns="columns"
      :request="loadDataTable"
      :row-key="(row) => row.id"
      ref="actionRef"
      :actionColumn="actionColumn"
      @edit-end="editEnd"
      @edit-change="onEditChange"
      @update:checked-row-keys="onCheckedRow"
    >
      <template #toolbar>
        <n-button type="primary" @click="reloadTable">刷新数据</n-button>
      </template>
    </BasicTable>
  </n-card>
</template>
<script lang="ts">
  import { defineComponent, reactive, toRefs, ref, h } from 'vue';
  import { BasicTable, TableAction } from '@/components/Table';
  import { getTableList } from '@/api/table/list';
  import { columns } from './rowColumns';
  export default defineComponent({
    components: { BasicTable },
    setup() {
      const actionRef = ref();
      const currentEditKeyRef = ref('');
      const state = reactive({
        params: {
          pageSize: 5,
          name: 'xiaoMa',
        },
        actionColumn: {
          width: 150,
          title: '操作',
          key: 'action',
          fixed: 'right',
          align: 'center',
          render(record) {
            return h(TableAction, {
              style: 'button',
              actions: createActions(record),
            });
          },
        },
      });

      function handleEdit(record) {
        currentEditKeyRef.value = record.key;
        record.onEdit?.(true);
      }

      function handleCancel(record: EditRecordRow) {
        currentEditKeyRef.value = '';
        record.onEdit?.(false, false);
      }

      function onEditChange({ column, value, record }) {
        if (column.dataIndex === 'id') {
          record.editValueRefs.name4.value = `${value}`;
        }
        console.log(column, value, record);
      }

      async function handleSave(record: EditRecordRow) {
        const pass = await record.onEdit?.(false, true);
        if (pass) {
          currentEditKeyRef.value = '';
        }
      }

      function createActions(record) {
        if (!record.editable) {
          return [
            {
              label: '编辑',
              onClick: handleEdit.bind(null, record),
            },
          ];
        } else {
          return [
            {
              label: '保存',
              onClick: handleSave.bind(null, record),
            },
            {
              label: '取消',
              onClick: handleCancel.bind(null, record),
            },
          ];
        }
      }

      const loadDataTable = async (params) => {
        const data = await getTableList(params);
        return data;
      };

      function onCheckedRow(rowKeys) {
        console.log(rowKeys);
      }

      function reloadTable() {
        console.log(actionRef.value);
        actionRef.value.reload();
      }
      
      function editEnd({ record, index, key, value }) {
        console.log(value);
      }
      
      return {
        ...toRefs(state),
        columns,
        actionRef,
        loadDataTable,
        onCheckedRow,
        reloadTable,
        editEnd,
        onEditChange,
      };
    },
  });
</script>

支持编辑组件

ts
import {
    NInput,
    NSelect,
    NCheckbox,
    NInputNumber,
    NSwitch,
    NDatePicker,
    NTimePicker,
} from 'naive-ui';

Props

温馨提醒

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

column

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

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

tableAction

ts
{
  // 按钮列表
  actions: Array;
  // 按钮风格 可选 `button`, `text`
  style?: String;
  // 更多按钮列表
  dropDownActions?: Array;
  // 更多按钮选择之后回调事件
  select?: Function;
}

tableAction.actions

ts
{
    //按钮点击
    onClick?: Fn;
    //按钮文字
    label?: string;
    //主题
    color?: 'success' | 'error' | 'warning';
    //图标,暂未实现
    icon?: string;
    //禁用
    disabled?: boolean;
    // 权限编码控制是否显示
    auth?: RoleEnum | RoleEnum[] | string | string[];
    // 业务控制是否显示
    ifShow?: boolean | ((action: ActionItem) => boolean);
}

事件

温馨提醒

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

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

edit-change 说明

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

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

Slots

温馨提醒

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

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