Skip to content

Commit

Permalink
feat: pagination && refactor code
Browse files Browse the repository at this point in the history
  • Loading branch information
lq782655835 committed May 7, 2020
1 parent de36fe5 commit 0cfa87c
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 59 deletions.
119 changes: 102 additions & 17 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default {
```
:::

## 全属性和事件支持
## 属性事件全继承elementui

自动集成el-table 和el-table-column所有属性和事件。el-table属性包括`stripe、border`等;el-table-column属性包括`fixed、align、show-overflow-tooltip`等。

Expand Down Expand Up @@ -64,7 +64,7 @@ export default {
list: listData,
columns: [
{ label: 'ID', prop: 'id', width: '80px', fixed: 'left' },
{ label: '存储卷名', prop: 'name', type: 'copy' },
{ label: '存储卷名', prop: 'name' },
{ label: '总容量', prop: 'storage' },
{ label: '邮箱', prop: 'member.email', 'show-overflow-tooltip': true },
{ label: '创建时间', prop: 'gmtCreate', align: 'right' }
Expand All @@ -84,8 +84,6 @@ export default {
```
:::

## 内置渲染组件

## 格式化列

element-ui字段列中有 [formatter](https://element.eleme.cn/#/zh-CN/component/table) - Function(row, column, cellValue, index) 属性支持格式化,这里el-table-plus兼容该写法。
Expand All @@ -111,7 +109,7 @@ export default {
list: listData,
columns: [
{ label: 'ID', prop: 'id', width: '80px' },
{ label: '存储卷名', prop: 'name', type: 'copy' },
{ label: '存储卷名', prop: 'name' },
{ label: '总容量', prop: 'storage', fn: val => `${val}G` },
{ label: '邮箱', prop: 'member.email' },
{ label: '创建时间', prop: 'gmtCreate' }
Expand Down Expand Up @@ -139,8 +137,8 @@ export default {
:columns="columns"
>
<template #handle="val, row">
<el-button type="primary" @click="detailHandle(row)">查看详情</el-button>
<el-button type="danger" @lick="this.delHandle(row)">删除</el-button>
<el-button size="small" type="primary" @click="detailHandle(row)">查看详情</el-button>
<el-button size="small" type="danger" @lick="this.delHandle(row)">删除</el-button>
</template>
</el-table-plus>
</template>
Expand All @@ -155,17 +153,17 @@ export default {
list: listData,
columns: [
{ label: 'ID', prop: 'id', width: '80px' },
{ label: '存储卷名', prop: 'name', type: 'copy' },
{ label: '存储卷名', prop: 'name' },
{ label: '总容量', prop: 'storage', fn: val => `${val}G` },
{ label: '邮箱', prop: 'member.email' },
{ label: '创建时间', prop: 'gmtCreate' },
{ label: '操作', fixed: 'right', prop: 'handle',
{ label: '操作', fixed: 'right', prop: 'handle', minWidth: '120px',
scopedSlots: { customRender: 'handle' },
// 同时customRender/customTitle支持JSX,返回VNode
// customRender: (val, row, column, index, h) => {
// return (<div>
// <el-button type="primary" onClick={() => this.detailHandle(row)}>查看详情</el-button>
// <el-button type="danger" onClick={() => this.delHandle(row)}>删除</el-button>
// <el-button size="small" type="primary" onClick={() => this.detailHandle(row)}>查看详情</el-button>
// <el-button size="small" type="danger" onClick={() => this.delHandle(row)}>删除</el-button>
// </div>)
// }
}
Expand Down Expand Up @@ -212,7 +210,7 @@ export default {
list: listData,
columns: [
{ label: 'ID', prop: 'id', width: '80px' },
{ label: '存储卷名', prop: 'name', type: 'copy' },
{ label: '存储卷名', prop: 'name' },
{ label: '总容量', prop: 'storage', sortable: 'custom', 'sort-orders': ['ascending', 'descending'] },
{ label: '邮箱', prop: 'member.email' },
{ label: '创建时间', prop: 'gmtCreate' }
Expand Down Expand Up @@ -277,8 +275,8 @@ export default {
:columns="columns"
>
<template #handle="text, row">
<el-button type="primary" @click="detailHandle(row)">查看详情</el-button>
<el-button type="danger" @lick="this.delHandle(row)">删除</el-button>
<el-button size="small" type="primary" @click="detailHandle(row)">查看详情</el-button>
<el-button size="small" type="danger" @lick="this.delHandle(row)">删除</el-button>
</template>
<template #handleTitle="column, index">
<el-input size="mini" placeholder="输入关键字搜索"/>
Expand All @@ -296,11 +294,11 @@ export default {
list: listData,
columns: [
{ label: 'ID', prop: 'id', width: '80px' },
{ label: '存储卷名', prop: 'name', type: 'copy' },
{ label: '存储卷名', prop: 'name' },
{ label: '总容量', prop: 'storage', fn: val => `${val}G` },
{ label: '邮箱', prop: 'member.email' },
{ label: '创建时间', prop: 'gmtCreate' },
{ label: '操作', fixed: 'right', prop: 'handle',
{ label: '操作', fixed: 'right', prop: 'handle', minWidth: '120px',
scopedSlots: { customRender: 'handle', customTitle: 'handleTitle' },
}
]
Expand All @@ -319,4 +317,91 @@ export default {
```
:::

## 集成pagination
## scroll事件

:::demo
``` vue
<template>
<el-table-plus
:data="list"
:columns="columns"
height="250"
@scroll="scrollHandle"
/>
</template>
<script>
const listData = JSON.parse(
`{"code":200,"message":"success","data":[{"id":50745,"name":"rtBNhgqCDR","storage":8620,"member":{"id":50961,"userId":"51262","email":"Nu87YypnB@AK22e.rgu","projectRole":"Qa4ohl6qhT"},"mount":[{"mountType":"M8Rhh2Ntp6","mountName":"bFTDHyixr3","mountPath":"uwDTMtnbCW","userName":"nYIE5YoQve"},{"mountType":"8pUyKzNPjL","mountName":"TVaV7bjr1y","mountPath":"HoazVStmm5","userName":"nbGzaRjLjK"},{"mountType":"nD3hnojrY0","mountName":"vtJvtG05Jw","mountPath":"p5VWi1ptsi","userName":"8ERyVxGL3R"}],"gmtCreate":34327},{"id":51414,"name":"1A6ogTNZl1","storage":36580,"member":{"id":51767,"userId":"52603","email":"606UKO@AgasP.qmt","projectRole":"q8KkeQyD8f"},"mount":[{"mountType":"VG3JPYd4n5","mountName":"ijPznKZnUQ","mountPath":"SiQIq2ypee","userName":"rAhVP1UTUQ"},{"mountType":"B900pSNnAf","mountName":"MGFUwpuZq2","mountPath":"RQJOgsV806","userName":"acfdNaETLA"},{"mountType":"L81aEPhXWJ","mountName":"7hWszN6MpP","mountPath":"e99n7mLoHe","userName":"t2d5oVwRqV"}],"gmtCreate":78533},{"id":52659,"name":"srO0gfnHho","storage":46240,"member":{"id":52998,"userId":"53927","email":"M37YXor@949Y0.acq","projectRole":"2ikIgsSabL"},"mount":[{"mountType":"YjxjSNSyOv","mountName":"lRsFRwSWgc","mountPath":"Z1rMIGu0cR","userName":"CoUSbae92N"},{"mountType":"N716xNCa4q","mountName":"uxYPo7TGcG","mountPath":"pXyJpuZ1CX","userName":"oiubmGJ4dQ"},{"mountType":"r3PqYBkT9y","mountName":"Pp6B1yZXhi","mountPath":"SjbANI8SmS","userName":"9h8k3elmdM"}],"gmtCreate":98416}]}`
).data
export default {
data() {
return {
list: Array(5).fill(listData).reduce((arr, current) => [...arr, ...current], []),
columns: [
{ label: 'ID', prop: 'id', width: '80px' },
{ label: '存储卷名', prop: 'name' },
{ label: '总容量', prop: 'storage' },
{ label: '邮箱', prop: 'member.email' },
{ label: '创建时间', prop: 'gmtCreate' }
]
};
},
methods: {
scrollHandle(e) {
console.log(e)
}
}
};
</script>
```
:::

## 集成pagination

分页器,参考配置项或 [pagination文档](https://element.eleme.cn/#/zh-CN/component/pagination#attributes),设为 false 时不展示和进行分页

:::demo
``` vue
<template>
<el-table-plus
:data="list"
:columns="columns"
:pagination="{layout:'prev, pager, next', background: true}"
:total="100"
@page-change="pageChangeHandle"
/>
</template>
<script>
const listData = JSON.parse(
`{"code":200,"message":"success","data":[{"id":50745,"name":"rtBNhgqCDR","storage":8620,"member":{"id":50961,"userId":"51262","email":"Nu87YypnB@AK22e.rgu","projectRole":"Qa4ohl6qhT"},"mount":[{"mountType":"M8Rhh2Ntp6","mountName":"bFTDHyixr3","mountPath":"uwDTMtnbCW","userName":"nYIE5YoQve"},{"mountType":"8pUyKzNPjL","mountName":"TVaV7bjr1y","mountPath":"HoazVStmm5","userName":"nbGzaRjLjK"},{"mountType":"nD3hnojrY0","mountName":"vtJvtG05Jw","mountPath":"p5VWi1ptsi","userName":"8ERyVxGL3R"}],"gmtCreate":34327},{"id":51414,"name":"1A6ogTNZl1","storage":36580,"member":{"id":51767,"userId":"52603","email":"606UKO@AgasP.qmt","projectRole":"q8KkeQyD8f"},"mount":[{"mountType":"VG3JPYd4n5","mountName":"ijPznKZnUQ","mountPath":"SiQIq2ypee","userName":"rAhVP1UTUQ"},{"mountType":"B900pSNnAf","mountName":"MGFUwpuZq2","mountPath":"RQJOgsV806","userName":"acfdNaETLA"},{"mountType":"L81aEPhXWJ","mountName":"7hWszN6MpP","mountPath":"e99n7mLoHe","userName":"t2d5oVwRqV"}],"gmtCreate":78533},{"id":52659,"name":"srO0gfnHho","storage":46240,"member":{"id":52998,"userId":"53927","email":"M37YXor@949Y0.acq","projectRole":"2ikIgsSabL"},"mount":[{"mountType":"YjxjSNSyOv","mountName":"lRsFRwSWgc","mountPath":"Z1rMIGu0cR","userName":"CoUSbae92N"},{"mountType":"N716xNCa4q","mountName":"uxYPo7TGcG","mountPath":"pXyJpuZ1CX","userName":"oiubmGJ4dQ"},{"mountType":"r3PqYBkT9y","mountName":"Pp6B1yZXhi","mountPath":"SjbANI8SmS","userName":"9h8k3elmdM"}],"gmtCreate":98416}]}`
).data
export default {
data() {
return {
list: listData,
columns: [
{ label: 'ID', prop: 'id', width: '80px' },
{ label: '存储卷名', prop: 'name' },
{ label: '总容量', prop: 'storage' },
{ label: '邮箱', prop: 'member.email' },
{ label: '创建时间', prop: 'gmtCreate' }
]
};
},
methods: {
pageChangeHandle({ pageSize, currentPage }) {
console.log(pageSize, currentPage)
}
}
};
</script>
<style>
.el-pagination {
margin-top: 10px;
margin-left: -10px;
}
</style>
```
:::
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
},
"dependencies": {
"core-js": "^2.6.5",
"lodash": "^4.17.15",
"vue": "^2.6.10"
},
"devDependencies": {
Expand Down
10 changes: 9 additions & 1 deletion src/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
@row-click="rowClickHandle"
@sort-change="sortChangeHandle"
stripe
border>
border
:pagination="{layout:'prev, pager, next', background: true, small: true}"
:total="100"
@page-change="pageChangeHandle"
>
<template #handle="text, row">
<el-button type="primary" @click="detailHandle(row)">查看详情</el-button>
<el-button type="danger" @lick="this.delHandle(row)">删除</el-button>
Expand Down Expand Up @@ -84,6 +88,10 @@ export default {
sortChangeHandle(o) {
console.log(o)
},
pageChangeHandle(e) {
console.log(e)
// console.log(pageSize, currentPage)
},
// formatter
formatter(row, column, cellValue, index) {
Expand Down
114 changes: 78 additions & 36 deletions src/components/el-table-plus.jsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,84 @@
import UCopy from './u-copy'
import { omit } from 'lodash'

export default {
name: "el-table-plus",
components: {
UCopy
},
props: {
// 动效loading
loading: { type: Boolean },
// 列表数据
data: { type: Array, default: () => [] },
columns: { type: Array, default: () => [] }
loading: { type: Boolean }, // 动效loading
data: { type: Array, default: () => [] }, // 列表数据
columns: { type: Array, default: () => [] }, // 列配置
// 翻页条设置
pagination: { type: [Object, Boolean], default: false },
total: { type: Number, default: 0 }
},
data() {
return {
pageSize: this.pagination && this.pagination.pageSize || 20,
currentPage: this.pagination && this.pagination.currentPage || 1,
tableWrap: null
}
},
mounted() {
const table = this.$refs.table
this.tableWrap = table.bodyWrapper

table.bodyWrapper.addEventListener('scroll', this.tableScroll)
this.$once('hook:beforeDestroy', () => {
this.tableWrap.removeEventListener('scroll', this.tableScroll)
})
},
methods: {
tableScroll(e) {
e.preventDefault()
this.$emit('scroll', e)
},
pageSizeChange(pageSize) {
this.pageSize = pageSize
this.emitPageChangeEvent()
},
currentChange(currentPage) {
this.currentPage = currentPage
this.emitPageChangeEvent()
},
emitPageChangeEvent() {
this.$emit('page-change', {
pageSize: this.pageSize,
currentPage: this.currentPage,
})
}
},
render(h) {
const getDataValue = (column, row) => column.prop.split(".").reduce((obj, cur) => obj[cur], row);
const renderColumns = columns => columns.filter(i => !i.hidden).map(column => {
column = Object.assign({scopedSlots: {}, prop: ''}, column)
const tableListeners = omit(this.$listeners, ['page-change'])

const getCellValue = (column, row) => column.prop.split(".").reduce((obj, cur) => obj[cur], row);

const renderColumns = columns => columns.filter(i => !i.hidden).map(c => {
const options = Object.assign({scopedSlots: {}, prop: ''}, c)

const scopedSlots = {
default: ({ row, column: elColumn, $index}) => {

const mergedColumn = Object.assign({}, elColumn, column)
const column = Object.assign({}, options, elColumn)

// 支持链式. 如:xxx.xxx
const defaultValue = getDataValue(column, row)

// 预设组件
if (column.type === 'copy') {
return <u-copy label={defaultValue} />
}
// 动态组件
if (['el-', 'dynamic-'].some(prefix => column.type && column.type.startsWith(prefix))) {
return h(column.type, { props: column }, defaultValue)
}
const defaultValue = getCellValue(column, row)

// 自定义组件
column.customRender = column.customRender || this.$scopedSlots[column.scopedSlots.customRender]
if (column.customRender) {
return column.customRender(defaultValue, row, mergedColumn, $index, h)
return column.customRender(defaultValue, row, column, $index, h)
}
// 自定义文字
if (column.fn) {
return column.fn(defaultValue, row, mergedColumn, $index)
return column.fn(defaultValue, row, column, $index)
}
// 兼容element-ui formatter属性
if (column.formatter) {
return column.formatter(row, mergedColumn, defaultValue, $index)
return column.formatter(row, column, defaultValue, $index)
}

return defaultValue
},
header: ({column: elColumn, $index}) => {
const column = Object.assign({}, options, elColumn)
column.customTitle = column.customTitle || this.$scopedSlots[column.scopedSlots.customTitle]
if (column.customTitle) {
return column.customTitle(elColumn, $index)
Expand All @@ -58,16 +87,29 @@ export default {
}
}

return <el-table-column key={column.prop} {...{props: column}} scopedSlots={scopedSlots} />
return <el-table-column key={options.prop} {...{props: options}} scopedSlots={scopedSlots} />
})

return (<el-table
ref="table"
v-loading={this.loading}
data={this.data}
{...{props: this.$attrs, on: this.$listeners}}
>
{renderColumns(this.columns)}
</el-table>)
return (
<div class="el-table-plus" v-loading={this.loading}>
<el-table
ref="table"
data={this.data}
{...{props: this.$attrs, on: tableListeners}}
>
{renderColumns(this.columns)}
</el-table>
{
this.pagination && (
<el-pagination
{...{ props: this.pagination }}
total={this.total}
on-size-change={this.pageSizeChange}
on-current-change={this.currentChange}
/>
)
}
</div>
)
}
};
5 changes: 0 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1144,11 +1144,6 @@
error-stack-parser "^2.0.0"
string-width "^2.0.0"

"@springleo/30-seconds-of-code@^1.0.3":
version "1.0.3"
resolved "https://registry.npmjs.org/@springleo/30-seconds-of-code/-/30-seconds-of-code-1.0.3.tgz#b9c9334fbacb0c1102e48b2e78da0adef0d2a8ec"
integrity sha512-KgiWWFiubBgL/qxsbo04tB9+G2f0S0YtKg7Ai//j03xI1bWsB8uHvsfvrF3Y5p17JMmeHDuRqpoF2W5fImLvxA==

"@szmarczak/http-timer@^1.1.2":
version "1.1.2"
resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
Expand Down

0 comments on commit 0cfa87c

Please sign in to comment.