基于iView 支持异步以及同步模式。
/**
* pageProps.pageSize pageProps.current 为必填项
* 可以通过调用实例方法在外层控制组件
*/
export default {
props: {
tableProps: {
type: Object,
default: () => {
}
},
pageProps: {
type: Object,
default: () => {
return {pageSize: 10, current: 1}
}
},
/**
* 如果是Function则必须返回Promise对象,表示表格数据从后端异步获取
* 若果为数组则是整个表格的全部数据,在前端处理分页排序
*/
tableData: {
type: [Function, Array],
required: true
}
},
data () {
return {
sortFuncMap: {},
current: this.pageProps.current || 1,
data: [],
total: 0,
pageSize: this.pageProps.pageSize || 10,
orderKey: '',
order: 'normal',
loading: false,
// 移除columns sortMethods 之后
processedTableProps: {}
}
},
computed: {
isAsync () {
return typeof this.tableData === 'function'
},
sortable () {
return this.orderKey && this.order && this.order !== 'normal'
},
_tableProps () {
return Object.assign({}, this.processedTableProps, {
data: this.data,
stripe: true,
loading: this.loading
})
},
_pageProps () {
return Object.assign({}, this.pageProps, {
total: this.total,
current: this.current,
pageSize: this.pageSize
})
}
},
created () {
this.setSort()
},
methods: {
// 清除column sortMethod方法 设置orderKey order 初始值
setSort () {
let orderKey, order
const props = _.cloneDeep(this.tableProps)
this.tableProps.columns.forEach(column => {
if (column.sortMethod && column.sortable) {
this.sortFuncMap[column.key] = column.sortMethod
if (column.sortType) {
if (orderKey || order) {
throw new Error('同时只能支持一个column排序')
}
orderKey = column.key
order = column.sortType
}
delete column['sortMethod']
}
})
this.processedTableProps = props
this.orderKey = orderKey
this.order = order
},
onSortChange ({key, order}) {
this.orderKey = key
this.order = order
this.setCurrent(1)
},
onSelectionChange: function (selection) {
this.$emit('on-select', selection)
},
onSizeChange: function (val) {
this.pageSize = val
this.setCurrent(1)
},
setCurrent (page) {
// 换页时清空之前的选择
this.onSelectionChange([])
this.current = page
this.reloadTableData()
},
setData () {
this.total = this.tableData.length
let data = this.tableData
if (this.sortable) {
const newData = _.cloneDeep(this.tableData)
data = newData.sort((a, b) => {
const func = this.sortFuncMap[this.orderKey]
return this.order === 'asc' ? func(a, b) : func(b, a)
})
}
this.data = data.slice(
(this.current - 1) * this.pageSize,
this.current * this.pageSize
)
},
reloadTableData () {
if (this.isAsync) {
const sortProps = {current: this.current, pageSize: this.pageSize}
if (this.sortable) {
sortProps.orderKey = this.orderKey
sortProps.order = this.order
}
this.loading = true
this.tableData(sortProps)
.then(({tableData, total}) => {
this.data = tableData
this.total = total
this.loading = false
})
.catch(() => {
this.data = []
this.total = 0
this.$Message.error('加载表格数据出错')
this.loading = false
})
} else {
this.setData()
}
}
},
mounted () {
this.reloadTableData()
},
watch: {
'tableData': function () {
this.reloadTableData()
},
'tableProps': function () {
this.setSort()
}
},
render: function (h) {
const children = [
h('Table', {
props: this._tableProps,
on: {
'on-sort-change': this.onSortChange,
'on-selection-change': this.onSelectionChange
}
})
]
if (this.total > this.pageSize) {
children.push(h('Page', {
props: this._pageProps,
on: {
'on-change': this.setCurrent,
'@on-page-size-change="changeSize': this.onSizeChange
}
}))
}
return h('div', children)
}
}
// 前端分页表格配置
const data = {
data: [],
pageProps: {
pageSize: 10
},
tableProps: {
columns: [
{ title: 'IOC', key: 'ioc' },
{ title: 'IP地址', key: 'ip' },
{
title: '命中数量',
key: 'count',
width: 120,
sortable: true,
sortType: 'desc',
sortMethod (a, b) {
return Number(a.count) - Number(b.count)
}
},
{ title: '地理位置', key: 'location' }
]
}
}
<template>
<div>
<page-table
ref="table"
:table-props="tableProps"
:page-props="pageProps"
:load-data="loadData"/>
</div>
</template>
<script>
import PageTable from '@/components/PageTableAsync'
import nameMixin from './nameMixin'
import json2csv from 'json2csv'
import download from 'downloadjs'
import http from '@/api'
export default {
components: {
PageTable
},
mixins: [nameMixin(false)],
data () {
return {
pageProps: {
pageSize: 10
},
tableProps: {
columns: [
{ title: '#', key: 'index', width: 40 },
{ title: '类型', key: 'type', width: 100 },
{ title: 'IOC', key: 'ioc' },
{
title: '命中数量',
key: 'count',
width: 120,
sortable: true,
sortType: 'desc',
sortMethod (a, b) {
return Number(a.count) - Number(b.count)
}
}
]
},
tableData: []
}
},
methods: {
loadNameData () {
this.$refs.table.reloadTableData()
},
loadData ({ current, pageSize }) {
return http.get('apt/campaign/ioc', {
params: {
name: this.name,
limit: pageSize,
page: current
}
}).then(data => {
return {
tableData: data.data.map((item, index) => Object.assign({}, item, { index })),
total: data.total
}
})
}
}
}
</script>