Skip to content
On this page

FatTableSelect

FatTableSelect 是一个基于 FatTable 扩展的一个Select Table; 在使用上也基本类似,FatTable上能使用的基本上都可以在FatTableSelect上使用





1. 快速创建一个页面



查看代码
tsx
import { defineFatTableSelect } from '@wakeadmin/components';
import { ElButton } from 'element-plus';

enum ItemStatus {
  Initial,
  Pending,
  Done,
}

/**
 * 列表项定义
 */
interface Item {
  id: number;
  name: string;
  status: ItemStatus;
  createdDate: number;
}

/**
 * 表单查询
 */
interface Query {
  name: string;
  status: ItemStatus;
}

export default defineFatTableSelect<Item, Query, { name: string; id: number }>(({ column }) => {
  return () => ({
    title: '明月如霜',
    rowKey: 'id',
    async request(params) {
      const { pagination, query } = params;

      // 模拟请求
      const mockData: Item[] = new Array(pagination.pageSize).fill(0).map((_, idx) => {
        const r = Math.floor(Math.random() * 1000);
        return {
          id: idx,
          name: `${r}-${pagination.page}-${query?.name ?? ''}`,
          status: r % 3 === 0 ? ItemStatus.Pending : r % 2 === 0 ? ItemStatus.Initial : ItemStatus.Done,
          createdDate: Date.now(),
        };
      });

      return {
        list: mockData,
        total: 100,
      };
    },
    renderBottomToolbar(_, selectedList) {
      const item = selectedList[0];
      if (item) {
        return () => (
          <div>
            当前选中:
            <div>
              名称 -{'>'} {item.name}
            </div>
            <div>
              id -{'>'} {item.id}
            </div>
          </div>
        );
      }
    },
    renderNavBar() {
      return (
        <span>
          <ElButton type="primary">创建</ElButton>
        </span>
      );
    },
    columns: [
      column({
        prop: 'name',
        label: '名称',
        queryable: true,
        valueType: 'search',
      }),
      column({
        prop: 'status',
        label: '状态',
        queryable: true,
        valueType: 'select',
        valueProps: {
          options: [
            { label: '未开始', value: ItemStatus.Initial, color: 'blue' },
            { label: '正在进行', value: ItemStatus.Pending, color: 'green' },
            { label: '已结束', value: ItemStatus.Done, color: 'gray' },
          ],
        },
      }),
      column({
        prop: 'createdDate',
        label: '创建时间',
        valueType: 'date-time',
        minWidth: 110,
      }),
    ],
  });
});

可以发现,在点击了选择之后,无论是点击搜索还是重置,我们的选择值都不会发生变化,这非常符合表格选择的逻辑,即选中的值跟当前表格所展示的数据并没有什么太多的关联


2. defineFatTableSelect(推荐)

我们推荐使用 defineFatTableSelect + TSX 来快速定义一个表格组件,使用 defineFatTableSelect 可以获取到更好的智能提示和类型检查。



defineFatTableSelect 大致用法如下:

tsx
interface Item {
  // 列表项类型声明
}

interface Query {
  // 表单查询类型声明
}
interface Selection {
  // 已选择项类型声明
}

export const MySelectTable = defineFatTableSelect<Item, Item, Selection>(({ table, column }) => {
  // 和 vue 的 setup 方法一样, 这里可以放置 Vue Composition API
  const someRef = ref(0);
  const someMethod = () => {};

  // 返回 FatTableSelect props
  return () => ({
    // 列表请求
    async request(params) {
      // ...
    },
    // 列定义
    columns: [
      // ...
    ],
    // 是否多选
    multiple: true,
    // 已选择的值
    value: [
      { name: '沙溪急', id: 229 },
      { name: '霜溪冷', id: 170 },
      { name: '月溪明', id: 155 },
    ],
    // ... 其他 FatTableSelect props
  });
});

defineFatTableSelect 类似于 defineFatTable

当然也可以用 template 来写, 会丢失上下文信息(vue 组件不支持泛型)。 其用法与fatTable基本一致,除此之外,因为FatTableSelect是表单项,因此也支持v-model语法。




3. 操作

默认情况下,FatTableSelect会有一些预定义场景:

  1. 如果multipletrue的话,那么会自动开启enableSelect,并且会插入一个默认的BottomToolbar
  2. 如果multiplefalse的话, 如果用户没有传入action列的话,那么会自动插入一条默认的action列;当然,我们也可以传入自定义的action来处理我们的操作逻辑。

WARNING

FatTableSelect会忽略用户传入的enableSelect

enableSelectmultiple是强绑定的。


查看代码
tsx
import { defineFatTableSelect } from '@wakeadmin/components';

export default defineFatTableSelect<any, any, { name: string }>(() => {
  return () => ({
    title: '表格操作',
    async request() {
      return {
        list: new Array(10).fill('S').map((_, i) => ({
          name: `MentalHealth${i + 1}`,
          id: i,
        })),
        total: 10,
      };
    },
    renderBottomToolbar(_, selectedList) {
      const item = selectedList[0];
      if (item) {
        return () => (
          <div>
            当前选中:
            <div>
              名称 -{'>'} {item.name}
            </div>
          </div>
        );
      }
    },
    enablePagination: false,

    rowKey: 'id',

    columns: [
      { label: '名称', prop: 'name' },
      {
        type: 'actions',
        label: '操作',
        // 支持传入一个函数,常用于一些需要动态计算的场景
        actions: () => {
          return [
            {
              name: 'Are you Ready?',
              title: '提示信息',
            },
            {
              name: '我好了',
              type: 'danger',
              onClick(table, row) {
                table.select(row);
              },
            },
            {
              name: '等一下,我还没好',
              type: 'warning',
              onClick(table, row) {
                table.unselect(row);
              },
            },
          ];
        },
      },
    ],
  });
});



除此之外,我们也挺支持全选、反选。不仅如此,还可以传入一个selectable来处理该项是否允许选择。在多选情况下,我们也支持传入limit来限制用户的选择个数。

查看代码
tsx
import { defineFatTableSelect } from '@wakeadmin/components';
import { defineComponent, ref } from 'vue';
import { ElButton } from 'element-plus';

export default defineComponent({
  name: 'TableSelectDisabledActions',
  setup() {
    const multiple = ref(false);
    const Table = defineFatTableSelect<any, any, { name: string; id: number }>(({ column }) => {
      const list = [
        { name: '女曰鸡鸣', id: 51024 },
        { name: '士曰昧旦', id: 15629 },
        { name: '子兴视夜', id: 588 },
        { name: '明星有烂', id: 5836 },
        { name: '将翱将翔', id: 9170 },
        { name: '弋凫与雁', id: 51658 },
        { name: '弋言加之', id: 4416 },
        { name: '与子宜之', id: 69 },
        { name: '宜言饮酒', id: 51918 },
        { name: '与子偕老', id: 52751 },
        { name: '琴瑟在御', id: 11157 },
        { name: '莫不静好', id: 56022 },
      ];
      return () => ({
        title: '好风如水',
        rowKey: 'id',
        limit: 6,
        batchActions: table => [
          {
            name: '全选',
            onClick: () => table.selectAll(),
          },
          {
            name: '反选',
            onClick: () => table.toggleAll(),
          },
          {
            name: '取消全选',
            onClick: () => table.unselectAll(),
          },
          {
            name: '清空',
            onClick: () => table.clear(),
          },
        ],
        async request(params) {
          const {
            pagination: { page, pageSize },
          } = params;

          return {
            list: list.slice((page - 1) * pageSize, pageSize * page),
            total: list.length,
          };
        },

        selectable(item) {
          return item.id % 10 !== 9;
        },
        onChange(payload) {
          console.log(payload.values);
        },
        columns: [
          column({
            prop: 'name',
            label: '名称',
          }),
          column({
            prop: 'id',
            label: 'id',
          }),
        ],
      });
    });

    return () => {
      return (
        <div>
          <ElButton
            onClick={() => {
              multiple.value = !multiple.value;
            }}
          >
            切换选择状态
          </ElButton>

          {multiple.value ? <Table key="s"></Table> : <Table key="m" multiple></Table>}
        </div>
      );
    };
  },
});

WARNING

暴露出来的selectAllunSelectAlltoggleAll都是针对于当前页面的数据,并且如果页面里的某条数据不允许操作,那么也不会对其进行处理。

但是selectunSelect这两个方法则没有过多的额外操作,传入什么就处理什么,不会关注于该条数据是否在当前页面里、是否禁用等





4. V-Model

FatTableSelect的返回值跟传入的value值相关。对于传入的value值,我们约定其数据格式类型为SelectionSelection的定义如下

  • 基础数据类型, 即 string 或者为number。 该模式下,FatTableSelect会直接返回对应的rowKey的值

  • Object,且该Object必须为Item的子集。 该模式下, FatTableSelect会按照传入的数据格式返回对应的值

  • undefined,该模式下,会直接返回整个item对象

查看代码
vue
<template>
  <div>
    <Table0 v-model="value0"></Table0>
    <Table1 v-model="value1"></Table1>
    <Table2 v-model="value2"></Table2>
    <Table3 v-model="value3"></Table3>
  </div>
</template>
<script setup lang="ts">
  import { defineFatTableSelect } from '@wakeadmin/components';
  import { ref, effect } from 'vue';

  interface Item {
    name: string;
    id: number;
  }
  type Selection = Partial<Item> | number | string;

  function createTableSelect<T extends Selection>(title: string) {
    return defineFatTableSelect<Item, any, T>({
      title,
      rowKey: 'id',
      limit: 6,
      multiple: true,
      columns: [
        {
          prop: 'name',
          label: '名称',
        },
        {
          prop: 'id',
          label: 'id',
        },
      ],
      async request() {
        return {
          list: [
            { name: '女曰鸡鸣', id: 51024 },
            { name: '士曰昧旦', id: 15629 },
            { name: '子兴视夜', id: 588 },
            { name: '明星有烂', id: 5836 },
            { name: '将翱将翔', id: 9170 },
            { name: '弋凫与雁', id: 51658 },
            { name: '弋言加之', id: 4416 },
            { name: '与子宜之', id: 69 },
            { name: '宜言饮酒', id: 51918 },
            { name: '与子偕老', id: 52751 },
          ],
          total: 10,
        };
      },
    });
  }

  const Table0 = createTableSelect('传入的是undefined');
  const Table1 = createTableSelect<string>('传入的是基本数据类型');
  const Table2 = createTableSelect<{ id: number }>('传入一个单独的id对象');
  const Table3 = createTableSelect<{ id: number; name: string }>('传入其他的对象');

  const value0 = ref([]);
  const value1 = ref([51024]);
  const value2 = ref([{ id: 51024 }]);
  const value3 = ref([{ id: 51024, name: '女曰鸡鸣' }]);

  effect(() => {
    console.log('Table0 ->', value0.value);
  });
  effect(() => {
    console.log('Table1 ->', value1.value);
  });
  effect(() => {
    console.log('Table2 ->', value2.value);
  });
  effect(() => {
    console.log('Table3 ->', value3.value);
  });
</script>

可以打开控制台查看其具体的输出




5. 自定义布局

FatTableSelect 默认布局使用的是 FatContainer, 你也可以按照自己的需求实现自定义的布局。

6. 与FatTable的区别

  1. 本质上 FatTableSelect 属于表单项, 与 Select 类似

  2. 以下props将由FatTableSelect控制,不允许用户自定义

    • enableSelect
    • selectable
    • onSelect
    • onLoad
  3. 不支持以下几个FatTableprops

  • enableCacheQuery
  • onQueryCacheRestore
  • confirmBeforeRemove
  • messageOnRemoved
  • messageOnRemoveFailed
  • remove
  • requestOnRemoved
  • confirmBeforeRemove
  • onSelect-all
  1. 默认情况下 会对FatTableColumns做一些处理

    • 如果multipletrue的话,那么会自动开启enableSelect,并且会插入一个默认的BottomToolbar

    • 如果multiplefalse的话, 如果用户没有传入action列的话,那么会自动插入一条默认的action列;当然,我们也可以传入自定义的action来处理我们的操作逻辑。

  2. 提供了一系列操作API

  3. 对外暴露的对象中里没有以下属性

  • selected

7. API

7.1 FatTableSelect 属性





7.2 FatTableSelect 事件




7.3 FatTableSelect 实例方法




FatTableSelect 实例方式获取有两种方式:

  1. defineFatTableSelect 函数参数 table 属性中获取:

    ts
    defineFatTableSelect(({ tableSelect }) => {});
    

  1. <template> 中,使用 useFatTableSelectRef:

    vue
    <template>
      <FatTableSelect ref="tableRef">...</FatTableSelect>
    </template>
    
    <script setup lang="tsx">
      import { FatTableSelect, useFatTableSelectRef } from '@wakeadmin/components';
    
      const tableRef = useFatTableSelectRef();
    </script>
    



7.4 FatTableSelect 插槽

FatTable一致




7.5 列定义

FatTable一致