Table 表格
静态数据渲染
1. 静态表单普通用法
代码示例
· 直接使用 ElPlusTable
<ElPlusTable v-model="tableData" :tableConfig="tableConfig" :isPager="false" />
<ElPlusTable v-model="tableData" :tableConfig="tableConfig" :isPager="false" />
· setup 中
let tableData = reactive([
{ id: 1, name: '张三', sex: '男', age: 55, address: '北京XXXX' },
{ id: 2, name: '李四', sex: '女', age: 24, address: '北京XXXX' },
{ id: 3, name: '王五', sex: '男', age: 4, address: '北京XXXX' }
])
const tableConfig = ref({
column: [
{ prop: 'name', label: '名字' },
{ prop: 'sex', label: '性别' },
{ prop: 'age', label: '年龄' },
{ prop: 'address', label: '地址' }
]
} as ITableConfig)
let tableData = reactive([
{ id: 1, name: '张三', sex: '男', age: 55, address: '北京XXXX' },
{ id: 2, name: '李四', sex: '女', age: 24, address: '北京XXXX' },
{ id: 3, name: '王五', sex: '男', age: 4, address: '北京XXXX' }
])
const tableConfig = ref({
column: [
{ prop: 'name', label: '名字' },
{ prop: 'sex', label: '性别' },
{ prop: 'age', label: '年龄' },
{ prop: 'address', label: '地址' }
]
} as ITableConfig)
· 使用字符串特性
不会使用?参考 FormatData 配置项
let tableData = reactive([
{ id: 1, name: '张三', sex: 1, age: 55, address: '北京XXXX' },
{ id: 2, name: '李四', sex: 0, age: 24, address: '深圳XXXX' },
{ id: 3, name: '王五', sex: 1, age: 41, address: '上海XXXX' }
])
const tableConfig = ref({
column: [
{ prop: 'name', label: '名字' },
{ prop: 'sex', label: '性别', format: 'formatSex' },
{ prop: 'age', label: '年龄' },
{ prop: 'address', label: '地址' }
]
} as ITableConfig)
let tableData = reactive([
{ id: 1, name: '张三', sex: 1, age: 55, address: '北京XXXX' },
{ id: 2, name: '李四', sex: 0, age: 24, address: '深圳XXXX' },
{ id: 3, name: '王五', sex: 1, age: 41, address: '上海XXXX' }
])
const tableConfig = ref({
column: [
{ prop: 'name', label: '名字' },
{ prop: 'sex', label: '性别', format: 'formatSex' },
{ prop: 'age', label: '年龄' },
{ prop: 'address', label: '地址' }
]
} as ITableConfig)
2. 静态表单 属性用法 ElPlusTable 同样支持官方 ElementPlus Table 的大部分属性,在属性配置项中,使用 tableAttr: { xxx: 'xxx' } 的方式
代码示例
const tableConfig = ref({
tableAttr: { stripe: true },
column: [
{ prop: 'name', label: '名字' },
{ prop: 'sex', label: '性别', format: 'formatSex' },
{ prop: 'age', label: '年龄' },
{ prop: 'address', label: '地址' }
]
} as ITableConfig)
const tableConfig = ref({
tableAttr: { stripe: true },
column: [
{ prop: 'name', label: '名字' },
{ prop: 'sex', label: '性别', format: 'formatSex' },
{ prop: 'age', label: '年龄' },
{ prop: 'address', label: '地址' }
]
} as ITableConfig)
这里就不做多的介绍,主要演示 content 的特殊用法
代码示例
<ElPlusTable ref="tableListRef" v-model="tableData" :tableConfig="tableConfig" :isPager="false" />
<script lang="ts" setup>
const tableConfig = ref({
column: [
{ prop: 'name', label: '名字' },
{ prop: 'sex', label: '性别', format: 'formatSex' },
{
prop: 'age',
label: '年龄',
content: (data: any, formData: any) => {
return data > 50 ? '这个年龄大于50' : ''
}
},
{ prop: 'address', label: '地址' }
]
} as ITableConfig)
</script>
<ElPlusTable ref="tableListRef" v-model="tableData" :tableConfig="tableConfig" :isPager="false" />
<script lang="ts" setup>
const tableConfig = ref({
column: [
{ prop: 'name', label: '名字' },
{ prop: 'sex', label: '性别', format: 'formatSex' },
{
prop: 'age',
label: '年龄',
content: (data: any, formData: any) => {
return data > 50 ? '这个年龄大于50' : ''
}
},
{ prop: 'address', label: '地址' }
]
} as ITableConfig)
</script>
远程数据拉取
配置 fetch: (data) => Promise 属性获取远程数据进行渲染
代码示例
<ElPlusTable ref="tableListRef" :tableConfig="tableConfig" :isPager="false" />
<script lang="ts" setup>
const tableConfig = ref({
fetch: async (postData: any) => {
const result = { records: tableData }
return await new Promise((resolve) => {
setTimeout(() => resolve(result), 1000)
})
},
column: [
{ prop: 'name', label: '名字' },
{ prop: 'sex', label: '性别', format: 'formatSex' },
{ prop: 'age', label: '年龄' },
{ prop: 'address', label: '地址' }
]
} as ITableConfig)
</script>
<ElPlusTable ref="tableListRef" :tableConfig="tableConfig" :isPager="false" />
<script lang="ts" setup>
const tableConfig = ref({
fetch: async (postData: any) => {
const result = { records: tableData }
return await new Promise((resolve) => {
setTimeout(() => resolve(result), 1000)
})
},
column: [
{ prop: 'name', label: '名字' },
{ prop: 'sex', label: '性别', format: 'formatSex' },
{ prop: 'age', label: '年龄' },
{ prop: 'address', label: '地址' }
]
} as ITableConfig)
</script>
也可以直接引用 api 使用方法
import { queryPage } from '@/api/xxx'
const tableConfig = ref({
fetch: queryPage
//...
} as ITableConfig)
import { queryPage } from '@/api/xxx'
const tableConfig = ref({
fetch: queryPage
//...
} as ITableConfig)
TIP
注意: tableConfig 中定义了 fetch 属性,就不要再添加 v-model 绑定了,会出现性能问题,如果实在需要获取 table 中 fetch 的结果数据,请自行添加 inited 回调钩子!!!请悉知!
代码示例
<ElPlusTable ref="tableListRef" v-model="tableData" :tableConfig="tableConfig" :isPager="false" />
<ElPlusTable ref="tableListRef" @inited="tableData" :tableConfig="tableConfig" :isPager="false" />
<script lang="ts" setup>
const tableConfig = ref({
fetch: (postData: any) => new Promise()
//...
} as ITableConfig)
// 返回fetch 的结果数据
function tableData(data: any) {}
</script>
<ElPlusTable ref="tableListRef" v-model="tableData" :tableConfig="tableConfig" :isPager="false" />
<ElPlusTable ref="tableListRef" @inited="tableData" :tableConfig="tableConfig" :isPager="false" />
<script lang="ts" setup>
const tableConfig = ref({
fetch: (postData: any) => new Promise()
//...
} as ITableConfig)
// 返回fetch 的结果数据
function tableData(data: any) {}
</script>
分页表格
使用分页的前提,是从 fetch 调用接口获取数据,并配置 isPager: boolean 属性,来控制表格是否分页,默认为 true,配置 pageSize: number 属性来控制每页显示条数
代码示例
<ElPlusTable ref="tableListRef" v-bind="tableConfig" />
<script lang="ts" setup>
const tableConfig = ref({
pageSize: 2,
tableConfig: {
fetch: async (postData: any) => {
const result = { total: tableData.length, records: tableData.filter((item: any, i: number) => (postData.current - 1) * postData.size <= i && i <= postData.current * postData.size - 1), current: postData.current } // (current-1)*size<=i<=(current*size)-1
return await new Promise((resolve) => {
setTimeout(() => resolve(result), 1000)
})
},
column: [
{ prop: 'name', label: '名字' },
{ prop: 'sex', label: '性别', format: 'formatSex' },
{ prop: 'age', label: '年龄' },
{ prop: 'address', label: '地址' }
]
}
})
</script>
<ElPlusTable ref="tableListRef" v-bind="tableConfig" />
<script lang="ts" setup>
const tableConfig = ref({
pageSize: 2,
tableConfig: {
fetch: async (postData: any) => {
const result = { total: tableData.length, records: tableData.filter((item: any, i: number) => (postData.current - 1) * postData.size <= i && i <= postData.current * postData.size - 1), current: postData.current } // (current-1)*size<=i<=(current*size)-1
return await new Promise((resolve) => {
setTimeout(() => resolve(result), 1000)
})
},
column: [
{ prop: 'name', label: '名字' },
{ prop: 'sex', label: '性别', format: 'formatSex' },
{ prop: 'age', label: '年龄' },
{ prop: 'address', label: '地址' }
]
}
})
</script>
合并行/列
需要在列表配置 isColSpan: boolean / isRowSpan: boolean 属性。哪一项需要合并列,就给它配置 isRowSpan: true;如果要合并行,就需要给要合并的列表项都配置 isColSpan: true
注意: 这里的合并,是把相同并且相邻的数据进行自动合并
代码示例
<ElPlusTable ref="tableListRef" v-model="tableData" v-bind="tableConfig" :isPager="false" />
<script lang="ts" setup>
let tableData = reactive([
{ id: 1, name: '商品1', price: 10, sellPrice: 15, number: 10 },
{ id: 2, name: '商品1', price: 25.2, sellPrice: 25.2, number: 2 },
{ id: 3, name: '商品2', price: 25.2, sellPrice: 26, number: 12 },
{ id: 4, name: '商品1', price: 25.2, sellPrice: 28, number: 8 },
{ id: 5, name: '商品3', price: 2, sellPrice: 2, number: 6 }
])
const tableConfig = ref({
tableConfig: {
column: [
{ prop: 'id', label: 'id', minWidth: '120px' },
{ prop: 'name', label: '商品名称', minWidth: '120px', isRowSpan: true, align: 'center' },
{ prop: 'price', label: '价格', minWidth: '120px', format: 'yuan', isColSpan: true, align: 'center' },
{ prop: 'sellPrice', label: '销售价格', format: 'yuan', minWidth: '120px', isColSpan: true },
{ prop: 'number', label: '商品数量', minWidth: '120px' }
]
}
})
</script>
<ElPlusTable ref="tableListRef" v-model="tableData" v-bind="tableConfig" :isPager="false" />
<script lang="ts" setup>
let tableData = reactive([
{ id: 1, name: '商品1', price: 10, sellPrice: 15, number: 10 },
{ id: 2, name: '商品1', price: 25.2, sellPrice: 25.2, number: 2 },
{ id: 3, name: '商品2', price: 25.2, sellPrice: 26, number: 12 },
{ id: 4, name: '商品1', price: 25.2, sellPrice: 28, number: 8 },
{ id: 5, name: '商品3', price: 2, sellPrice: 2, number: 6 }
])
const tableConfig = ref({
tableConfig: {
column: [
{ prop: 'id', label: 'id', minWidth: '120px' },
{ prop: 'name', label: '商品名称', minWidth: '120px', isRowSpan: true, align: 'center' },
{ prop: 'price', label: '价格', minWidth: '120px', format: 'yuan', isColSpan: true, align: 'center' },
{ prop: 'sellPrice', label: '销售价格', format: 'yuan', minWidth: '120px', isColSpan: true },
{ prop: 'number', label: '商品数量', minWidth: '120px' }
]
}
})
</script>
TIP
目前 Table 表格还不能支持配置 span-method 属性,请悉知!
合计行数据
在 summaryConf 里配置 prop: string 和 label: string可实现该列表的金额合计数据
代码示例
<ElPlusTable ref="tableListRef" v-model="tableData" v-bind="tableConfig" :isPager="false" />
<script lang="ts" setup>
const tableConfig = ref({
tableConfig: {
summaryConf: {
prop: 'price',
label: '价格总计'
},
column: [
{ prop: 'id', label: 'id', minWidth: '120px' },
{ prop: 'name', label: '商品名称', minWidth: '120px', isRowSpan: true, align: 'center' },
{ prop: 'price', label: '价格', minWidth: '120px', format: 'yuan', isColSpan: true, align: 'center' },
{ prop: 'sellPrice', label: '销售价格', format: 'yuan', minWidth: '120px', isColSpan: true },
{ prop: 'number', label: '商品数量', minWidth: '120px' }
]
}
})
</script>
<ElPlusTable ref="tableListRef" v-model="tableData" v-bind="tableConfig" :isPager="false" />
<script lang="ts" setup>
const tableConfig = ref({
tableConfig: {
summaryConf: {
prop: 'price',
label: '价格总计'
},
column: [
{ prop: 'id', label: 'id', minWidth: '120px' },
{ prop: 'name', label: '商品名称', minWidth: '120px', isRowSpan: true, align: 'center' },
{ prop: 'price', label: '价格', minWidth: '120px', format: 'yuan', isColSpan: true, align: 'center' },
{ prop: 'sellPrice', label: '销售价格', format: 'yuan', minWidth: '120px', isColSpan: true },
{ prop: 'number', label: '商品数量', minWidth: '120px' }
]
}
})
</script>
添加 sumFn: ( tableData: any[ ], allSelectRowList: any[ ] ) => string 自定义合计方法
代码示例
<div class="demo">
<ElPlusTable ref="tableListRef" v-model="tableData" v-bind="table1Config" :isPager="false" />
</div>
<div class="demo">
<ElPlusTable ref="tableListRef" v-model="tableData" v-bind="table2Config" :isPager="false" />
</div>
<script lang="ts" setup>
import { inject } from 'vue'
const format = inject('format' as any)
const table1Config = ref({
tableConfig: {
summaryConf: {
prop: 'sellPrice',
label: '总销售价格',
sumFn: (tableData: any[]) => {
return format.yuan(
tableData.reduce((total: number, current: any) => {
return (total += current.sellPrice * current.number)
}, 0)
)
}
},
column: [
{ prop: 'id', label: 'id', minWidth: '120px' },
{ prop: 'name', label: '商品名称', minWidth: '120px', isRowSpan: true, align: 'center' },
{ prop: 'price', label: '价格', minWidth: '120px', format: 'yuan', isColSpan: true, align: 'center' },
{ prop: 'sellPrice', label: '销售价格', format: 'yuan', minWidth: '120px', isColSpan: true },
{ prop: 'number', label: '商品数量', minWidth: '120px' }
]
}
})
const table2Config = ref({
type: 'selection',
tableConfig: {
summaryConf: {
prop: 'sellPrice',
label: '总销售价格',
sumFn: (tableData: any[], allSelectRowList: any[]) => {
return format.yuan(
allSelectRowList.reduce((total: number, current: any) => {
return (total += current.sellPrice * current.number)
}, 0)
)
}
},
column: [
{ prop: 'id', label: 'id', minWidth: '120px' },
{ prop: 'name', label: '商品名称', minWidth: '120px', isRowSpan: true, align: 'center' },
{ prop: 'price', label: '价格', minWidth: '120px', format: 'yuan', isColSpan: true, align: 'center' },
{ prop: 'sellPrice', label: '销售价格', format: 'yuan', minWidth: '120px', isColSpan: true },
{ prop: 'number', label: '商品数量', minWidth: '120px' }
]
}
})
</script>
<div class="demo">
<ElPlusTable ref="tableListRef" v-model="tableData" v-bind="table1Config" :isPager="false" />
</div>
<div class="demo">
<ElPlusTable ref="tableListRef" v-model="tableData" v-bind="table2Config" :isPager="false" />
</div>
<script lang="ts" setup>
import { inject } from 'vue'
const format = inject('format' as any)
const table1Config = ref({
tableConfig: {
summaryConf: {
prop: 'sellPrice',
label: '总销售价格',
sumFn: (tableData: any[]) => {
return format.yuan(
tableData.reduce((total: number, current: any) => {
return (total += current.sellPrice * current.number)
}, 0)
)
}
},
column: [
{ prop: 'id', label: 'id', minWidth: '120px' },
{ prop: 'name', label: '商品名称', minWidth: '120px', isRowSpan: true, align: 'center' },
{ prop: 'price', label: '价格', minWidth: '120px', format: 'yuan', isColSpan: true, align: 'center' },
{ prop: 'sellPrice', label: '销售价格', format: 'yuan', minWidth: '120px', isColSpan: true },
{ prop: 'number', label: '商品数量', minWidth: '120px' }
]
}
})
const table2Config = ref({
type: 'selection',
tableConfig: {
summaryConf: {
prop: 'sellPrice',
label: '总销售价格',
sumFn: (tableData: any[], allSelectRowList: any[]) => {
return format.yuan(
allSelectRowList.reduce((total: number, current: any) => {
return (total += current.sellPrice * current.number)
}, 0)
)
}
},
column: [
{ prop: 'id', label: 'id', minWidth: '120px' },
{ prop: 'name', label: '商品名称', minWidth: '120px', isRowSpan: true, align: 'center' },
{ prop: 'price', label: '价格', minWidth: '120px', format: 'yuan', isColSpan: true, align: 'center' },
{ prop: 'sellPrice', label: '销售价格', format: 'yuan', minWidth: '120px', isColSpan: true },
{ prop: 'number', label: '商品数量', minWidth: '120px' }
]
}
})
</script>