feat: add ample demos to @pureadmin/table (#379)

* feat: add ample demos to @pureadmin/table
This commit is contained in:
RealityBoy
2022-11-21 11:42:33 +08:00
committed by GitHub
parent 8ff242ea45
commit 9b62d6ef1e
46 changed files with 1859 additions and 48 deletions

View File

@@ -100,7 +100,7 @@ const swiperExample: any[] = [
</template>
<el-row :gutter="10">
<el-col v-for="item in swiperExample" :key="item.id" :span="12">
<h3 class="py-[24px] text-[24px] font-bold">{{ item.label }}</h3>
<h6 class="py-[24px] text-[24px] font-bold">{{ item.label }}</h6>
<swiper v-bind="item.options">
<swiper-slide v-for="i in 5" :key="i">
<div

View File

@@ -39,7 +39,7 @@ const selectedVal = ({ left, right }): void => {
@selectedVal="selectedVal"
:disabled="item.disabled"
/>
<h4 v-if="!item.disabled">选中范围{{ selectRange }}</h4>
<h4 class="mt-3" v-if="!item.disabled">选中范围{{ selectRange }}</h4>
</el-card>
</div>
</template>

View File

@@ -0,0 +1,22 @@
<script setup lang="ts">
import { tableData } from "./data";
const columns: TableColumnList = [
{
label: "日期",
prop: "date"
},
{
label: "姓名",
prop: "name"
},
{
label: "地址",
prop: "address"
}
];
</script>
<template>
<pure-table :data="tableData" :columns="columns" />
</template>

View File

@@ -0,0 +1,22 @@
<script setup lang="ts">
import { tableData } from "./data";
const columns: TableColumnList = [
{
label: "日期",
prop: "date"
},
{
label: "姓名",
prop: "name"
},
{
label: "地址",
prop: "address"
}
];
</script>
<template>
<pure-table :data="tableData" :columns="columns" border />
</template>

View File

@@ -0,0 +1,70 @@
import { message } from "@pureadmin/components";
import { tableData } from "../data";
// 如果您不习惯tsx写法可以传slot然后在template里写
// 需是hooks写法函数中有return避免失去响应性
export function useColumns() {
const columns: TableColumnList = [
{
label: "日期",
prop: "date",
cellRenderer: ({ row }) => (
<div style="display: flex; align-items: center">
<iconify-icon-online icon="ep:timer" />
<span style="margin-left: 10px">{row.date}</span>
</div>
)
},
{
label: "姓名",
prop: "name",
cellRenderer: ({ row }) => (
<el-popover effect="light" trigger="hover" placement="top" width="auto">
{{
default: () => (
<>
<div>name: {row.name}</div>
<div>address: {row.address}</div>
</>
),
reference: () => <el-tag>{row.name}</el-tag>
}}
</el-popover>
)
},
{
label: "地址",
prop: "address"
},
{
label: "操作",
cellRenderer: ({ index, row }) => (
<>
<el-button size="small" onClick={() => handleEdit(index + 1, row)}>
Edit
</el-button>
<el-button
size="small"
type="danger"
onClick={() => handleDelete(index + 1, row)}
>
Delete
</el-button>
</>
)
}
];
const handleEdit = (index: number, row) => {
message.success(`您编辑了第 ${index} 行,数据为:${JSON.stringify(row)}`);
};
const handleDelete = (index: number, row) => {
message.error(`您删除了第 ${index} 行,数据为:${JSON.stringify(row)}`);
};
return {
columns,
tableData
};
}

View File

@@ -0,0 +1,9 @@
<script setup lang="ts">
import { useColumns } from "./columns";
const { columns, tableData } = useColumns();
</script>
<template>
<pure-table :data="tableData" :columns="columns" />
</template>

View File

@@ -0,0 +1,30 @@
<script setup lang="ts">
import { tableData } from "./data";
const indexMethod = (index: number) => {
return index * 2;
};
const columns: TableColumnList = [
{
type: "index",
index: indexMethod
},
{
label: "日期",
prop: "date"
},
{
label: "姓名",
prop: "name"
},
{
label: "地址",
prop: "address"
}
];
</script>
<template>
<pure-table :data="tableData" :columns="columns" />
</template>

View File

@@ -0,0 +1,285 @@
import dayjs from "dayjs";
import { clone } from "@pureadmin/utils";
const date = dayjs(new Date()).format("YYYY-MM-DD");
const tableData = [
{
date,
name: "Tom",
address: "No. 189, Grove St, Los Angeles"
},
{
date,
name: "Jack",
address: "No. 189, Grove St, Los Angeles"
},
{
date,
name: "Dick",
address: "No. 189, Grove St, Los Angeles"
},
{
date,
name: "Harry",
address: "No. 189, Grove St, Los Angeles"
},
{
date,
name: "Sam",
address: "No. 189, Grove St, Los Angeles"
},
{
date,
name: "Lucy",
address: "No. 189, Grove St, Los Angeles"
},
{
date,
name: "Mary",
address: "No. 189, Grove St, Los Angeles"
},
{
date,
name: "Mike",
address: "No. 189, Grove St, Los Angeles"
}
];
const cloneData = clone(tableData, true);
const tableDataMore = cloneData.map(item =>
Object.assign(item, {
state: "California",
city: "Los Angeles",
"post-code": "CA 90036"
})
);
const tableDataSortable = cloneData.map((item, index) =>
Object.assign(item, {
date: `${dayjs(new Date()).format("YYYY-MM")}-${index + 1}`
})
);
const tableDataExpand = [
{
date: "2016-05-03",
name: "Tom",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114",
family: [
{
name: "Jerry",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
},
{
name: "Spike",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
},
{
name: "Tyke",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
}
]
},
{
date: "2016-05-02",
name: "Tom",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114",
family: [
{
name: "Jerry",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
},
{
name: "Spike",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
},
{
name: "Tyke",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
}
]
},
{
date: "2016-05-04",
name: "Tom",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114",
family: [
{
name: "Jerry",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
},
{
name: "Spike",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
},
{
name: "Tyke",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
}
]
},
{
date: "2016-05-01",
name: "Tom",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114",
family: [
{
name: "Jerry",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
},
{
name: "Spike",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
},
{
name: "Tyke",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
}
]
},
{
date: "2016-05-08",
name: "Tom",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114",
family: [
{
name: "Jerry",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
},
{
name: "Spike",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
},
{
name: "Tyke",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
}
]
},
{
date: "2016-05-06",
name: "Tom",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114",
family: [
{
name: "Jerry",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
},
{
name: "Spike",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
},
{
name: "Tyke",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
}
]
},
{
date: "2016-05-07",
name: "Tom",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114",
family: [
{
name: "Jerry",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
},
{
name: "Spike",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
},
{
name: "Tyke",
state: "California",
city: "San Francisco",
address: "3650 21st St, San Francisco",
zip: "CA 94114"
}
]
}
];
export { tableData, tableDataMore, tableDataSortable, tableDataExpand };

View File

@@ -0,0 +1,72 @@
<script setup lang="ts">
import { ref } from "vue";
import { tableDataExpand } from "./data";
const parentBorder = ref(false);
const childBorder = ref(false);
const columns: TableColumnList = [
{
type: "expand",
slot: "expand"
},
{
label: "日期",
prop: "date"
},
{
label: "姓名",
prop: "name"
}
];
const childColumns: TableColumnList = [
{
label: "Name",
prop: "name"
},
{
label: "State",
prop: "state"
},
{
label: "City",
prop: "city"
},
{
label: "Address",
prop: "address"
},
{
label: "Zip",
prop: "zip"
}
];
</script>
<template>
<div>
switch parent border: <el-switch v-model="parentBorder" /> switch child
border: <el-switch v-model="childBorder" />
<pure-table
:data="tableDataExpand"
:columns="columns"
:border="parentBorder"
>
<template #expand="{ row }">
<div class="m-4">
<p class="mb-2">State: {{ row.state }}</p>
<p class="mb-2">City: {{ row.city }}</p>
<p class="mb-2">Address: {{ row.address }}</p>
<p class="mb-4">Zip: {{ row.zip }}</p>
<h3>Family</h3>
<pure-table
:data="row.family"
:columns="childColumns"
:border="childBorder"
/>
</div>
</template>
</pure-table>
</div>
</template>

View File

@@ -0,0 +1,104 @@
<script setup lang="ts">
import { ref } from "vue";
const tableRef = ref();
const clearFilter = val => {
const { clearFilter } = tableRef.value.getTableRef();
clearFilter(val);
};
const resetDateFilter = () => {
clearFilter(["date"]);
};
const filterTag = (value, row) => {
return row.tag === value;
};
const filterHandler = (value, row, column) => {
const property = column["property"];
return row[property] === value;
};
const columns: TableColumnList = [
{
label: "日期",
prop: "date",
sortable: true,
columnKey: "date",
filters: [
{ text: "2016-05-01", value: "2016-05-01" },
{ text: "2016-05-02", value: "2016-05-02" },
{ text: "2016-05-03", value: "2016-05-03" },
{ text: "2016-05-04", value: "2016-05-04" }
],
filterMethod: filterHandler
},
{
label: "姓名",
prop: "name"
},
{
label: "地址",
prop: "address"
},
{
label: "标签",
prop: "tag",
filters: [
{ text: "Home", value: "Home" },
{ text: "Office", value: "Office" }
],
filterMethod: filterTag,
filterPlacement: "bottom-end",
slot: "tag"
}
];
const tableData = [
{
date: "2016-05-03",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
tag: "Home"
},
{
date: "2016-05-02",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
tag: "Office"
},
{
date: "2016-05-04",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
tag: "Home"
},
{
date: "2016-05-01",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
tag: "Office"
}
];
</script>
<template>
<div>
<el-button @click="resetDateFilter">reset date filter</el-button>
<el-button @click="clearFilter">reset all filters</el-button>
<pure-table
ref="tableRef"
row-key="date"
:data="tableData"
:columns="columns"
>
<template #tag="{ row }">
<el-tag :type="row.tag === 'Home' ? '' : 'success'" disable-transitions>
{{ row.tag }}
</el-tag>
</template>
</pure-table>
</div>
</template>

View File

@@ -0,0 +1,79 @@
<script setup lang="ts">
import { tableDataMore } from "./data";
const props = withDefaults(
defineProps<{
height?: string;
}>(),
{
height: null
}
);
const columns: TableColumnList = [
{
label: "日期",
prop: "date",
width: "260",
fixed: true
},
{
label: "姓名",
prop: "name",
width: "260"
},
{
label: "地区",
prop: "state",
width: "260"
},
{
label: "城市",
prop: "city",
width: "260"
},
{
label: "地址",
prop: "address",
width: "260"
},
{
label: "邮编",
prop: "post-code",
width: "260"
},
{
label: "操作",
width: "120",
fixed: "right",
slot: "operation"
}
];
function handleClick(row) {
console.log(
"%crow===>>>: ",
"color: MidnightBlue; background: Aquamarine; font-size: 20px;",
row
);
}
</script>
<template>
<pure-table
:data="
props.height
? tableDataMore.concat(tableDataMore).concat(tableDataMore)
: tableDataMore
"
:columns="columns"
:height="props.height"
>
<template #operation="{ row }">
<el-button link type="primary" size="small" @click="handleClick(row)">
Detail
</el-button>
<el-button link type="primary" size="small">Edit</el-button>
</template>
</pure-table>
</template>

View File

@@ -0,0 +1,26 @@
<script setup lang="ts">
import { tableData } from "./data";
const columns: TableColumnList = [
{
label: "日期",
prop: "date"
},
{
label: "姓名",
prop: "name"
},
{
label: "地址",
prop: "address"
}
];
</script>
<template>
<pure-table
:data="tableData.concat(tableData).concat(tableData)"
:columns="columns"
height="360"
/>
</template>

View File

@@ -0,0 +1,84 @@
<script setup lang="ts">
import { ref } from "vue";
import dayjs from "dayjs";
import { tableDataMore } from "./data";
const columns: TableColumnList = [
{
label: "日期",
prop: "date",
width: "260",
fixed: true
},
{
label: "姓名",
prop: "name",
width: "260"
},
{
label: "地区",
prop: "state",
width: "260"
},
{
label: "城市",
prop: "city",
width: "260"
},
{
label: "地址",
prop: "address",
width: "260"
},
{
label: "邮编",
prop: "post-code",
width: "260"
},
{
label: "操作",
width: "120",
fixed: "right",
slot: "operation"
}
];
const now = new Date();
const tableData = ref(tableDataMore);
const deleteRow = (index: number) => {
tableData.value.splice(index, 1);
};
const onAddItem = () => {
now.setDate(now.getDate() + 1);
tableData.value.push({
date: dayjs(now).format("YYYY-MM-DD"),
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
state: "California",
city: "Los Angeles",
"post-code": "CA 90036"
});
};
</script>
<template>
<div>
<pure-table :data="tableData" :columns="columns" maxHeight="500">
<template #operation="{ $index }">
<el-button
link
type="primary"
size="small"
@click.prevent="deleteRow($index)"
>
Remove
</el-button>
</template>
</pure-table>
<el-button class="mt-4" style="width: 100%" @click="onAddItem">
Add Item
</el-button>
</div>
</template>

View File

@@ -0,0 +1,38 @@
<script setup lang="ts">
import { tableDataMore } from "./data";
const columns: TableColumnList = [
{
label: "日期",
prop: "date",
fixed: true
},
{
label: "姓名",
prop: "name",
children: [
{
label: "地区",
children: [
{
label: "城市",
prop: "city"
},
{
label: "地址",
prop: "address"
}
]
}
]
},
{
label: "邮编",
prop: "post-code"
}
];
</script>
<template>
<pure-table :data="tableDataMore" :columns="columns" alignWhole="center" />
</template>

View File

@@ -0,0 +1,70 @@
import { message } from "@pureadmin/components";
import { tableData } from "../data";
import { ref, computed } from "vue";
// 如果您不习惯tsx写法可以传slot然后在template里写
// 需是hooks写法函数中有return避免失去响应性
export function useColumns() {
const search = ref("");
const filterTableData = computed(() =>
tableData.filter(
data =>
!search.value ||
data.name.toLowerCase().includes(search.value.toLowerCase())
)
);
const handleEdit = (index: number, row) => {
message.success(`您编辑了第 ${index} 行,数据为:${JSON.stringify(row)}`);
};
const handleDelete = (index: number, row) => {
message.error(`您删除了第 ${index} 行,数据为:${JSON.stringify(row)}`);
};
const columns: TableColumnList = [
{
label: "日期",
prop: "date"
},
{
label: "姓名",
prop: "name"
},
{
label: "地址",
prop: "address"
},
{
align: "right",
// 自定义表头
headerRenderer: () => (
<el-input
v-model={search.value}
size="small"
clearable
placeholder="Type to search"
/>
),
cellRenderer: ({ index, row }) => (
<>
<el-button size="small" onClick={() => handleEdit(index + 1, row)}>
Edit
</el-button>
<el-button
size="small"
type="danger"
onClick={() => handleDelete(index + 1, row)}
>
Delete
</el-button>
</>
)
}
];
return {
columns,
filterTableData
};
}

View File

@@ -0,0 +1,9 @@
<script setup lang="ts">
import { useColumns } from "./columns";
const { columns, filterTableData } = useColumns();
</script>
<template>
<pure-table :data="filterTableData" :columns="columns" />
</template>

View File

@@ -0,0 +1,43 @@
import Base from "./base.vue";
import Stripe from "./stripe.vue";
import Border from "./border.vue";
import Status from "./status.vue";
import FixHeader from "./fixHeader.vue";
import FixColumn from "./fixColumn.vue";
import FluidHeight from "./fluidHeight.vue";
import GroupHeader from "./groupHeader.vue";
import Radio from "./radio.vue";
import MultipleChoice from "./multipleChoice.vue";
import Sortable from "./sortable.vue";
import Filters from "./filters.vue";
import ColumnTemplate from "./column-template/index.vue";
import HeaderRenderer from "./header-renderer/index.vue";
import Expand from "./expand.vue";
import TreeTable from "./tree.vue";
import TotalRow from "./totalRow.vue";
import Merge from "./merge.vue";
import CustomIndex from "./customIndex.vue";
import Layout from "./layout.vue";
export {
Base,
Stripe,
Border,
Status,
FixHeader,
FixColumn,
FluidHeight,
GroupHeader,
Radio,
MultipleChoice,
Sortable,
Filters,
ColumnTemplate,
HeaderRenderer,
Expand,
TreeTable,
TotalRow,
Merge,
CustomIndex,
Layout
};

View File

@@ -0,0 +1,38 @@
<script setup lang="ts">
import { ref } from "vue";
import { tableData } from "./data";
type TableLayout = "fixed" | "auto";
const tableLayout = ref<TableLayout>("fixed");
const columns: TableColumnList = [
{
label: "日期",
prop: "date"
},
{
label: "姓名",
prop: "name"
},
{
label: "地址",
prop: "address"
}
];
</script>
<template>
<div>
<el-radio-group v-model="tableLayout">
<el-radio-button label="fixed" />
<el-radio-button label="auto" />
</el-radio-group>
<pure-table
:data="tableData"
:columns="columns"
:table-layout="tableLayout"
/>
</div>
</template>

View File

@@ -0,0 +1,124 @@
<script setup lang="ts">
interface User {
id: string;
name: string;
amount1: string;
amount2: string;
amount3: number;
}
interface SpanMethodProps {
row: User;
column: any;
rowIndex: number;
columnIndex: number;
}
const arraySpanMethod = ({ rowIndex, columnIndex }: SpanMethodProps) => {
if (rowIndex % 2 === 0) {
if (columnIndex === 0) {
return [1, 2];
} else if (columnIndex === 1) {
return [0, 0];
}
}
};
const objectSpanMethod = ({ rowIndex, columnIndex }: SpanMethodProps) => {
if (columnIndex === 0) {
if (rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1
};
} else {
return {
rowspan: 0,
colspan: 0
};
}
}
};
const tableData: User[] = [
{
id: "12987122",
name: "Tom",
amount1: "234",
amount2: "3.2",
amount3: 10
},
{
id: "12987123",
name: "Tom",
amount1: "165",
amount2: "4.43",
amount3: 12
},
{
id: "12987124",
name: "Tom",
amount1: "324",
amount2: "1.9",
amount3: 9
},
{
id: "12987125",
name: "Tom",
amount1: "621",
amount2: "2.2",
amount3: 17
},
{
id: "12987126",
name: "Tom",
amount1: "539",
amount2: "4.1",
amount3: 15
}
];
const columns: TableColumnList = [
{
label: "ID",
prop: "id"
},
{
label: "Name",
prop: "name"
},
{
label: "Amount 1",
prop: "amount1",
sortable: true
},
{
label: "Amount 2",
prop: "amount2",
sortable: true
},
{
label: "Amount 3",
prop: "amount3",
sortable: true
}
];
</script>
<template>
<div>
<pure-table
:data="tableData"
:columns="columns"
:span-method="arraySpanMethod"
border
/>
<pure-table
:data="tableData"
:columns="columns"
:span-method="objectSpanMethod"
border
/>
</div>
</template>

View File

@@ -0,0 +1,57 @@
<script setup lang="ts">
import { ref } from "vue";
import { tableData } from "./data";
const tableRef = ref();
const multipleSelection = ref([]);
const toggleSelection = (rows?: any) => {
const { toggleRowSelection, clearSelection } = tableRef.value.getTableRef();
if (rows) {
rows.forEach(row => {
toggleRowSelection(row, undefined);
});
} else {
clearSelection();
}
};
const handleSelectionChange = val => {
multipleSelection.value = val;
};
const columns: TableColumnList = [
{
type: "selection",
align: "left"
},
{
label: "日期",
prop: "date"
},
{
label: "姓名",
prop: "name"
},
{
label: "地址",
prop: "address"
}
];
</script>
<template>
<div>
<pure-table
ref="tableRef"
:data="tableData"
:columns="columns"
@selection-change="handleSelectionChange"
/>
<div style="margin-top: 20px">
<el-button @click="toggleSelection([tableData[1], tableData[2]])">
Toggle selection status of second and third rows
</el-button>
<el-button @click="toggleSelection()">Clear selection</el-button>
</div>
</div>
</template>

View File

@@ -0,0 +1,47 @@
<script setup lang="ts">
import { ref } from "vue";
import { tableData } from "./data";
const tableRef = ref();
const currentRow = ref();
const setCurrent = (row?: any) => {
// 获取表格的方法 tableRef.value.getTableRef()
const { setCurrentRow } = tableRef.value.getTableRef();
setCurrentRow(row);
};
const handleCurrentChange = val => {
currentRow.value = val;
};
const columns: TableColumnList = [
{
label: "日期",
prop: "date"
},
{
label: "姓名",
prop: "name"
},
{
label: "地址",
prop: "address"
}
];
</script>
<template>
<div>
<pure-table
ref="tableRef"
:data="tableData"
:columns="columns"
highlight-current-row
@current-change="handleCurrentChange"
/>
<div style="margin-top: 20px">
<el-button @click="setCurrent(tableData[1])">Select second row</el-button>
<el-button @click="setCurrent()">Clear selection</el-button>
</div>
</div>
</template>

View File

@@ -0,0 +1,28 @@
<script setup lang="ts">
import { tableDataSortable } from "./data";
const columns: TableColumnList = [
{
label: "日期",
prop: "date",
sortable: true
},
{
label: "姓名",
prop: "name"
},
{
label: "地址",
prop: "address",
formatter: ({ address }) => `格式化后的内容:${address}`
}
];
</script>
<template>
<pure-table
:data="tableDataSortable"
:columns="columns"
:default-sort="{ prop: 'date', order: 'ascending' }"
/>
</template>

View File

@@ -0,0 +1,46 @@
<script setup lang="ts">
import { tableData } from "./data";
const tableRowClassName = ({ rowIndex }: { rowIndex: number }) => {
if (rowIndex === 1 || rowIndex === 5) {
return "pure-warning-row";
} else if (rowIndex === 3 || rowIndex === 7) {
return "pure-success-row";
}
return "";
};
const columns: TableColumnList = [
{
label: "日期",
prop: "date"
},
{
label: "姓名",
prop: "name"
},
{
label: "地址",
prop: "address"
}
];
</script>
<template>
<pure-table
:data="tableData"
:columns="columns"
:row-class-name="tableRowClassName"
/>
</template>
<style>
/* 此处样式会在全局都生效,上面 tableRowClassName 函数返回的值也就是类名必须在全局中唯一,避免样式突出 */
.pure-warning-row {
--el-table-tr-bg-color: var(--el-color-warning-light-9);
}
.pure-success-row {
--el-table-tr-bg-color: var(--el-color-success-light-9);
}
</style>

View File

@@ -0,0 +1,22 @@
<script setup lang="ts">
import { tableData } from "./data";
const columns: TableColumnList = [
{
label: "日期",
prop: "date"
},
{
label: "姓名",
prop: "name"
},
{
label: "地址",
prop: "address"
}
];
</script>
<template>
<pure-table :data="tableData" :columns="columns" stripe />
</template>

View File

@@ -0,0 +1,144 @@
<script setup lang="ts">
interface Product {
id: string;
name: string;
amount1: string;
amount2: string;
amount3: number;
}
interface SummaryMethodProps<T = Product> {
columns: any[];
data: T[];
}
const getSummaries = (param: SummaryMethodProps) => {
const { columns, data } = param;
const sums: string[] = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = "Total Cost";
return;
}
const values = data.map(item => Number(item[column.property]));
if (!values.every(value => Number.isNaN(value))) {
sums[index] = `$ ${values.reduce((prev, curr) => {
const value = Number(curr);
if (!Number.isNaN(value)) {
return prev + curr;
} else {
return prev;
}
}, 0)}`;
} else {
sums[index] = "N/A";
}
});
return sums;
};
const tableData: Product[] = [
{
id: "12987122",
name: "Tom",
amount1: "234",
amount2: "3.2",
amount3: 10
},
{
id: "12987123",
name: "Tom",
amount1: "165",
amount2: "4.43",
amount3: 12
},
{
id: "12987124",
name: "Tom",
amount1: "324",
amount2: "1.9",
amount3: 9
},
{
id: "12987125",
name: "Tom",
amount1: "621",
amount2: "2.2",
amount3: 17
},
{
id: "12987126",
name: "Tom",
amount1: "539",
amount2: "4.1",
amount3: 15
}
];
const columns: TableColumnList = [
{
label: "ID",
prop: "id"
},
{
label: "Name",
prop: "name"
},
{
label: "Amount 1",
prop: "amount1",
sortable: true
},
{
label: "Amount 2",
prop: "amount2",
sortable: true
},
{
label: "Amount 3",
prop: "amount3",
sortable: true
}
];
const columns1: TableColumnList = [
{
label: "ID",
prop: "id"
},
{
label: "Name",
prop: "name"
},
{
label: "Cost 1 ($)",
prop: "amount1"
},
{
label: "Cost 2 ($)",
prop: "amount2"
},
{
label: "Cost 3 ($)",
prop: "amount3"
}
];
</script>
<template>
<pure-table
:data="tableData"
:columns="columns"
border
show-summary
class="mb-6"
/>
<pure-table
:data="tableData"
:columns="columns1"
border
:summary-method="getSummaries"
show-summary
/>
</template>

View File

@@ -0,0 +1,122 @@
<script setup lang="ts">
interface User {
id: number;
date: string;
name: string;
hasChildren?: boolean;
children?: User[];
}
const load = (
row: User,
treeNode: unknown,
resolve: (date: User[]) => void
) => {
setTimeout(() => {
resolve([
{
id: 31,
date: "2016-05-01",
name: "wangxiaohu"
},
{
id: 32,
date: "2016-05-01",
name: "wangxiaohu"
}
]);
}, 1000);
};
const tableData: User[] = [
{
id: 1,
date: "2016-05-02",
name: "wangxiaohu"
},
{
id: 2,
date: "2016-05-04",
name: "wangxiaohu"
},
{
id: 3,
date: "2016-05-01",
name: "wangxiaohu",
children: [
{
id: 31,
date: "2016-05-01",
name: "wangxiaohu"
},
{
id: 32,
date: "2016-05-01",
name: "wangxiaohu"
}
]
},
{
id: 4,
date: "2016-05-03",
name: "wangxiaohu"
}
];
const tableData1: User[] = [
{
id: 1,
date: "2016-05-02",
name: "wangxiaohu"
},
{
id: 2,
date: "2016-05-04",
name: "wangxiaohu"
},
{
id: 3,
date: "2016-05-01",
name: "wangxiaohu",
hasChildren: true
},
{
id: 4,
date: "2016-05-03",
name: "wangxiaohu"
}
];
const columns: TableColumnList = [
{
label: "日期",
prop: "date"
},
{
label: "姓名",
prop: "name"
}
];
</script>
<template>
<div>
<pure-table
:data="tableData"
:columns="columns"
row-key="id"
border
default-expand-all
class="mb-6"
/>
<pure-table
:data="tableData1"
:columns="columns"
row-key="id"
border
lazy
:load="load"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
/>
</div>
</template>

View File

@@ -0,0 +1,46 @@
<script setup lang="ts">
import { list } from "./list";
import { Tabs, TabPane } from "@pureadmin/components";
defineOptions({
name: "PureTable"
});
</script>
<template>
<el-card>
<template #header>
<div class="card-header">
<span class="font-medium">
平台二次封装 element-plus Table 完全兼容 Api
并提供灵活的配置项以及完善的类型提醒再也不用将代码都写在 template
里了欢迎 Star
<el-link
href="https://github.com/xiaoxian521/pure-admin-table"
target="_blank"
style="font-size: 16px; margin: 0 4px 5px"
>
@pureadmin/table
</el-link>
</span>
</div>
</template>
<Tabs :destroyInactiveTabPane="true">
<TabPane v-for="item of list" :key="item.key">
<template #tab>
<el-tooltip :content="item.content" placement="top-end">
<span>{{ item.title }}</span>
</el-tooltip>
</template>
<component :is="item.component" />
</TabPane>
</Tabs>
</el-card>
</template>
<style scoped>
:deep(.ant-tabs-content-holder) {
margin-top: 10px;
}
</style>

View File

@@ -0,0 +1,154 @@
import {
Base,
Stripe,
Border,
Status,
FixHeader,
FixColumn,
FluidHeight,
GroupHeader,
Radio,
MultipleChoice,
Sortable,
Filters,
ColumnTemplate,
HeaderRenderer,
Expand,
TreeTable,
TotalRow,
Merge,
CustomIndex,
Layout
} from "./components";
const rendContent = (val: string) =>
`代码位置src/views/pure-table/components/${val}.vue`;
export const list = [
{
key: "base",
content: rendContent("base"),
title: "基础表格",
component: Base
},
{
key: "stripe",
content: rendContent("stripe"),
title: "带斑马纹表格",
component: Stripe
},
{
key: "border",
content: rendContent("border"),
title: "带边框表格",
component: Border
},
{
key: "status",
content: rendContent("status"),
title: "带状态表格",
component: Status
},
{
key: "fixHeader",
content: rendContent("fixHeader"),
title: "固定表头",
component: FixHeader
},
{
key: "fixColumn",
content: rendContent("fixColumn"),
title: "固定列",
component: FixColumn
},
{
key: "fixColumnHeader",
content: rendContent("fixColumn"),
title: "固定列和表头",
component: () => <FixColumn height={"360"} />
},
{
key: "groupHeader",
content: rendContent("groupHeader"),
title: "多级表头(表头分组)",
component: GroupHeader
},
{
key: "fluidHeight",
content: rendContent("fluidHeight"),
title: "流体高度",
component: FluidHeight
},
{
key: "radio",
content: rendContent("radio"),
title: "单选",
component: Radio
},
{
key: "multipleChoice",
content: rendContent("multipleChoice"),
title: "多选",
component: MultipleChoice
},
{
key: "sortable",
content: rendContent("sortable"),
title: "排序和格式化",
component: Sortable
},
{
key: "filters",
content: rendContent("filters"),
title: "筛选",
component: Filters
},
{
key: "column-template",
content: rendContent("column-template/index"),
title: "自定义列模板",
component: ColumnTemplate
},
{
key: "header-renderer",
content: rendContent("header-renderer/index"),
title: "自定义表头",
component: HeaderRenderer
},
{
key: "expand",
content: rendContent("expand"),
title: "展开行",
component: Expand
},
{
key: "tree",
content: rendContent("tree"),
title: "树形数据与懒加载",
component: TreeTable
},
{
key: "totalRow",
content: rendContent("totalRow"),
title: "表尾合计行",
component: TotalRow
},
{
key: "merge",
content: rendContent("merge"),
title: "合并行或列",
component: Merge
},
{
key: "customIndex",
content: rendContent("customIndex"),
title: "自定义索引",
component: CustomIndex
},
{
key: "layout",
content: rendContent("layout"),
title: "表格布局",
component: Layout
}
];

View File

@@ -1,8 +1,7 @@
import { ref } from "vue";
import dayjs from "dayjs";
export function useColumns() {
const columns = ref([
const columns: TableColumnList = [
{
type: "selection",
width: 55,
@@ -13,7 +12,6 @@ export function useColumns() {
label: "序号",
type: "index",
width: 60,
align: "left",
hide: ({ checkList }) => !checkList.includes("序号列")
},
{
@@ -58,7 +56,7 @@ export function useColumns() {
width: 140,
slot: "operation"
}
]);
];
return {
columns

View File

@@ -99,11 +99,12 @@ onMounted(() => {
</el-button>
</template>
<template v-slot="{ size, checkList }">
<PureTable
<pure-table
ref="tableRef"
border
align="center"
align-whole="center"
row-key="id"
showOverflowTooltip
table-layout="auto"
default-expand-all
:size="size"
@@ -142,7 +143,7 @@ onMounted(() => {
</template>
</el-popconfirm>
</template>
</PureTable>
</pure-table>
</template>
</TableProBar>
</div>

View File

@@ -6,10 +6,11 @@ import { Switch, message } from "@pureadmin/components";
export function useColumns() {
const switchLoadMap = ref({});
const columns = ref([
const columns: TableColumnList = [
{
type: "selection",
width: 55,
align: "left",
hide: ({ checkList }) => !checkList.includes("勾选列")
},
{
@@ -60,7 +61,7 @@ export function useColumns() {
unCheckedValue={0}
checked-children="已开启"
un-checked-children="已关闭"
onChange={() => onChange(scope)}
onChange={() => onChange(scope as any)}
/>
)
},
@@ -77,7 +78,7 @@ export function useColumns() {
width: 180,
slot: "operation"
}
]);
];
function onChange({ row, index }) {
ElMessageBox.confirm(

View File

@@ -118,9 +118,9 @@ onMounted(() => {
</el-button>
</template>
<template v-slot="{ size, checkList }">
<PureTable
<pure-table
border
align="center"
align-whole="center"
showOverflowTooltip
table-layout="auto"
:size="size"
@@ -199,7 +199,7 @@ onMounted(() => {
</template>
</el-dropdown>
</template>
</PureTable>
</pure-table>
</template>
</TableProBar>
</div>

View File

@@ -6,10 +6,11 @@ import { Switch, message } from "@pureadmin/components";
export function useColumns() {
const switchLoadMap = ref({});
const columns = ref([
const columns: TableColumnList = [
{
type: "selection",
width: 55,
align: "left",
hide: ({ checkList }) => !checkList.includes("勾选列")
},
{
@@ -65,7 +66,7 @@ export function useColumns() {
unCheckedValue={0}
checked-children="已开启"
un-checked-children="已关闭"
onChange={() => onChange(scope)}
onChange={() => onChange(scope as any)}
/>
)
},
@@ -82,7 +83,7 @@ export function useColumns() {
width: 180,
slot: "operation"
}
]);
];
function onChange({ row, index }) {
ElMessageBox.confirm(

View File

@@ -131,9 +131,9 @@ onMounted(() => {
</el-button>
</template>
<template v-slot="{ size, checkList }">
<PureTable
<pure-table
border
align="center"
align-whole="center"
table-layout="auto"
:size="size"
:data="dataList"
@@ -211,7 +211,7 @@ onMounted(() => {
</template>
</el-dropdown>
</template>
</PureTable>
</pure-table>
</template>
</TableProBar>
</div>