Appearance
SimpleTable 简单表格
简易的table组件,满足大部分需求,如需要高度定制的table,请使用 useTable
。
提示
- 示例中存在边框样式问题(为文档框架内部影响),实际使用无此问题。
- 请求逻辑依赖了公共hook的 useTable 的useTable。
基础用法
包含基础的表格渲染,单选、多选,(区别于a-table,这里的勾选会保留翻页效果,且存储在hasSelectedRows内,hasSelectedRows会包含选择的全量信息)
序号 | 姓名 | 年龄 | 详细地址 | |
---|---|---|---|---|
暂无数据 |
允许翻页
复制代码
查看代码
<template>
<div class="selected-info" v-if="hasSelectedRows.length">
已选择 {{ hasSelectedRows.length }} 项
<a-button type="link" @click="hasSelectedRows = []">清空</a-button>
</div>
<s-simple-table
:fetch-func="fetchData"
:columns="columns"
:fetch-params="{ type: 'user' }"
:row-selection="{
type: 'checkbox',
}"
:has-pagination="hasPagination"
v-model:hasSelectedRows="hasSelectedRows"
bordered
>
<!-- 自定义单元格 -->
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'age'">
<a-tag :color="record.age > 40 ? 'red' : 'green'">
{{ text }}
</a-tag>
</template>
</template>
<!-- 自定义列标题 -->
<template #headerCell="{ column }">
<template v-if="column.dataIndex === 'address'">
<span style="color: #1890ff">详细地址</span>
</template>
</template>
</s-simple-table>
<a-flex vertical :gap="10">
<a-space>
<a-button @click="selectSpecialRows()">初始化选中第二、第三行</a-button>
</a-space>
<a-space>
允许翻页
<a-switch v-model:checked="hasPagination" />
</a-space>
</a-flex>
</template>
<script setup lang="ts">
import { ref } from "vue";
const hasSelectedRows = ref<any[]>([]); // 勾选条目
const hasPagination = ref(true);
const columns = [
{
title: "姓名",
dataIndex: "name",
key: "name",
},
{
title: "年龄",
dataIndex: "age",
key: "age",
},
{
title: "地址",
dataIndex: "address",
key: "address",
},
];
// 这里需要传入rowKey的项
const selectSpecialRows = () => {
hasSelectedRows.value = [{ id: 2 }, { id: 3 }];
};
const fetchData = async (params: any) => {
// 模拟接口请求
const { page = 1, size = 10 } = params;
const list = Array.from({ length: size }, (_, index) => ({
id: (page - 1) * size + index + 1,
name: `用户${(page - 1) * size + index + 1}`,
age: Math.floor(Math.random() * 50) + 20,
address: `北京市朝阳区xxx街道${(page - 1) * size + index + 1}号`,
}));
return {
success: true,
data: list,
totalCount: 100,
totalPages: 10
};
};
</script>
<style scoped>
.selected-info {
margin-bottom: 16px;
padding: 8px 16px;
background: #f5f5f5;
border-radius: 4px;
}
</style>
包含搜索的示例
整合QueryFilter组件,支持部分插槽定义(注:可内置使用,也可以自行使用query-filter配合使用)
内置查询此方式下,最外层无法获取到搜索字段,请打开f12查看参数输出
姓名
年龄
地址
序号 | 姓名 | 年龄 | 详细地址 |
---|---|---|---|
暂无数据 |
结合query-filter组件使用
复制代码
查看代码
<template>
<h4 v-if="!withQueryFilter">
内置查询<span class="text-[#999] ml-2 font-normal text-sm"
>此方式下,最外层无法获取到搜索字段,请打开f12查看参数输出</span
>
</h4>
<h4 v-else>结合query-filter使用</h4>
<s-query-filter
v-if="withQueryFilter"
:fields="fields"
:values="searchValues"
@search="handleSearch"
/>
<s-simple-table
ref="tableRef"
:fetch-func="fetchData"
:columns="columns"
:fetch-params="withQueryFilter ? searchValues : {}"
bordered
:need-query-filter="!withQueryFilter"
>
<!-- 整行的slot -->
<template #optBar>
<a-space>
<a-button type="primary">新增</a-button>
<a-button type="primary">导出</a-button>
</a-space>
</template>
<!-- 单独的slot-左 -->
<template #optBarLeft>
<a-space>
<a-button type="primary">新增</a-button>
<a-button type="primary">导出</a-button>
</a-space>
</template>
<!-- 单独的slot-右 -->
<template #optBarRight>
<a-space>
<a-button type="primary">新增</a-button>
<a-button type="primary">导出</a-button>
</a-space>
</template>
<!-- 自定义单元格 -->
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'age'">
<a-tag :color="record.age > 40 ? 'red' : 'green'">
{{ text }}
</a-tag>
</template>
</template>
<!-- 自定义列标题 -->
<template #headerCell="{ column }">
<template v-if="column.dataIndex === 'address'">
<span style="color: #1890ff">详细地址</span>
</template>
</template>
</s-simple-table>
<a-flex vertical :gap="10">
<a-space v-if="withQueryFilter"> 搜索值: {{ searchValues }} </a-space>
<a-space>
结合query-filter组件使用
<a-switch v-model:checked="withQueryFilter" />
</a-space>
</a-flex>
</template>
<script setup lang="ts">
import { ref } from "vue";
import type { IFieldType } from "@/components/QueryFilter/type";
const withQueryFilter = ref(false);
const searchValues = ref({
name: "",
age: [],
address: "",
});
const tableRef = ref<any>(null);
const fields = ref<IFieldType[]>([
{
label: "姓名",
fieldKey: "name",
fieldType: "input",
},
{
label: "年龄",
fieldKey: "age",
fieldType: "inputNumber",
},
{
label: "地址",
fieldKey: "address",
fieldType: "input",
},
]);
const columns = [
{
title: "姓名",
dataIndex: "name",
key: "name",
queryConfig: "input",
},
{
title: "年龄",
dataIndex: "age",
key: "age",
queryConfig: "inputNumber",
},
{
title: "地址",
dataIndex: "address",
key: "address",
queryConfig: "input",
},
];
const fetchData = async (params: any) => {
// 模拟接口请求
const { page = 1, size = 10 } = params;
const list = Array.from({ length: size }, (_, index) => ({
id: (page - 1) * size + index + 1,
name: `用户${(page - 1) * size + index + 1}`,
age: Math.floor(Math.random() * 50) + 20,
address: `北京市朝阳区xxx街道${(page - 1) * size + index + 1}号`,
}));
return {
success: true,
data: list,
totalCount: 100,
totalPages: 10
};
};
const handleSearch = (values: any) => {
searchValues.value = values;
tableRef.value.getList(); // 调用表格搜索
};
</style>
更自定义场景请参照useTable中的示例
API
Props
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
fetchFunc | 请求函数 | Function | - |
fetchParams | 请求参数(默认会携带上page,size参数) | Record<string, any> | {} |
columns | 列配置 | any[] | - |
rowKey | 行唯一标识 | string | 'id' |
showPagination | 是否显示分页(关闭会去掉内置page,size参数) | boolean | true |
showIndex | 是否显示序号 | boolean | true |
bordered | 是否显示边框 | boolean | false |
size | 表格大小 | 'small' | 'middle' | 'large' | 'middle' |
beforeFetch | 数据获取前的回调 | () => void | - |
afterFetch | 数据获取后的回调 | (data: any) => void | - |
transformAfterFetch | 请求后的参数转换(用于处理不符合标准参数的场景,先于afterFetch执行) | (data: any) => any | - |
Slots
插槽名 | 说明 | 参数 |
---|---|---|
- | 自定义列内容 | { text, record, index } |