feat(advance-table): fixed column, not finished

This commit is contained in:
JiwenBai 2019-10-23 19:04:55 +08:00
parent cabe887499
commit 8b34107f8b
5 changed files with 148 additions and 72 deletions

View File

@ -1,3 +1,11 @@
<!--
* @Author: Volankey@gmail.com
* @Company: Tusimple
* @Date: 2019-10-23 16:03:04
* @LastEditors: Jiwen.bai
* @LastEditTime: 2019-10-23 16:04:18
-->
# Basic # Basic
```html ```html
@ -76,6 +84,7 @@ const _columns3 = $this => {
{ {
title: 'Age', title: 'Age',
key: 'age', key: 'age',
width: 100,
sortable: true, sortable: true,
sorter(a, b) { sorter(a, b) {
return a.age - b.age return a.age - b.age
@ -98,6 +107,7 @@ const _columns3 = $this => {
{ {
title: 'Sex', title: 'Sex',
key: 'sex', key: 'sex',
width: 100,
onFilter: (values, record) => { onFilter: (values, record) => {
return values.includes(record.sex) return values.includes(record.sex)
}, },
@ -114,7 +124,6 @@ const _columns3 = $this => {
}, },
{ {
title: '#', title: '#',
fixed: 'right',
width: 200, width: 200,
render: (h, params) => { render: (h, params) => {
return ( return (

View File

@ -1,3 +1,11 @@
<!--
* @Author: Volankey@gmail.com
* @Company: Tusimple
* @Date: 2019-10-23 15:59:41
* @LastEditors: Jiwen.bai
* @LastEditTime: 2019-10-23 16:34:30
-->
# Senior Usage # Senior Usage
```html ```html
@ -62,7 +70,9 @@ const _columns3 = $this => {
sortable: 'custom', sortable: 'custom',
onFilter: (value, record) => { onFilter: (value, record) => {
return value.includes(record.name + '') return value.includes(record.name + '')
} },
width: 200,
fixed: 'left'
}, },
{ {
title: 'Age', title: 'Age',

View File

@ -1,6 +1,14 @@
<!--
* @Author: Volankey@gmail.com
* @Company: Tusimple
* @Date: 2019-10-23 16:06:59
* @LastEditors: Jiwen.bai
* @LastEditTime: 2019-10-23 16:48:42
-->
<template> <template>
<!-- table body --> <!-- table body -->
<n-table <n-table
ref="nTable"
:style="tableStl" :style="tableStl"
style="border-top-left-radius:0;border-top-right-radius:0;" style="border-top-left-radius:0;border-top-right-radius:0;"
@scroll.native="onBodyScrolll" @scroll.native="onBodyScrolll"
@ -81,14 +89,38 @@ export default {
row row
}, },
props: { props: {
tableStl: {}, tableStl: {
showingData: {}, type: Object,
columns: {}, default: () => ({})
rowClassName: {}, },
checkBoxes: {}, showingData: {
disabledCheckBox: {}, type: Array,
headerRefName: {}, default: () => []
loading: {} },
columns: {
type: Array,
default: () => []
},
rowClassName: {
type: [Function, String],
default: ''
},
checkBoxes: {
type: Array,
default: () => []
},
disabledCheckBox: {
type: Array,
default: () => []
},
headerRefName: {
type: String,
default: null
},
loading: {
type: Boolean,
default: false
}
}, },
data () { data () {
return {} return {}
@ -142,8 +174,7 @@ export default {
return className return className
}, },
onBodyScrolll (event) { onBodyScrolll (event) {
this.headerRealEl.style.transform = `translate3d(-${event.target.scrollLeft}px,0,0)` this.$emit('on-scroll', event)
event.stopPropagation()
} }
} }
} }

View File

@ -1,3 +1,10 @@
<!--
* @Author: Volankey@gmail.com
* @Company: Tusimple
* @Date: 2019-10-23 15:57:17
* @LastEditors: Jiwen.bai
* @LastEditTime: 2019-10-23 18:51:15
-->
<template> <template>
<div <div
ref="tableWrapper" ref="tableWrapper"
@ -29,6 +36,31 @@
</div> </div>
</div> </div>
<div ref="tbodyWrapper" class="n-advance-table__tbody"> <div ref="tbodyWrapper" class="n-advance-table__tbody">
<div class="n-advance-table__fixed--left">
<table-header
ref="fixedLeftHeader"
:columns="fixedLeftColumn"
:col-group-stl="colGroup"
:scroll-bar-width="scrollBarWidth"
:sort-indexs="sortIndexs"
:selected-filter="selectedFilter"
:showing-data="showingData"
@on-checkbox-all="onAllCheckboxesClick"
@on-sort-change="onSortChange"
@on-filter="onFilter"
/>
<table-body
ref="fixedLeftTbody"
:table-stl="tableStl"
:showing-data="showingData"
:columns="fixedLeftColumn"
:row-class-name="rowClassName"
:check-boxes="checkBoxes"
:disabled-check-box="disabledCheckBox"
:loading="loading"
header-ref-name="header"
/>
</div>
<!-- table head --> <!-- table head -->
<table-header <table-header
ref="header" ref="header"
@ -53,6 +85,7 @@
:disabled-check-box="disabledCheckBox" :disabled-check-box="disabledCheckBox"
:loading="loading" :loading="loading"
header-ref-name="header" header-ref-name="header"
@on-scroll="onBodyScrolll"
/> />
</div> </div>
<!-- 分页 --> <!-- 分页 -->
@ -66,8 +99,6 @@
</template> </template>
<script> <script>
// import SortIcon from '../sortIcon'
// import PopFilter from '../popFilter'
import searchInput from '../searchInput' import searchInput from '../searchInput'
import { noopFn } from '../../../utils/index' import { noopFn } from '../../../utils/index'
import withapp from '../../../mixins/withapp' import withapp from '../../../mixins/withapp'
@ -79,8 +110,6 @@ export default {
name: 'NAdvanceTable', name: 'NAdvanceTable',
components: { components: {
TableBody, TableBody,
// SortIcon,
// PopFilter,
searchInput, searchInput,
TableHeader TableHeader
}, },
@ -174,6 +203,30 @@ export default {
} }
}, },
computed: { computed: {
fixedLeftColumn () {
return this.columns
.filter(column => {
return column.fixed === 'left'
})
.map(item => {
return {
...item,
fixed: false
}
})
},
fixedRightColumn () {
return this.columns
.filter(column => {
return column.fixed === 'right'
})
.map(item => {
return {
...item,
fixed: false
}
})
},
currentSortColumn () { currentSortColumn () {
let sorterKey = null let sorterKey = null
let i = 0 let i = 0
@ -397,7 +450,7 @@ export default {
this.tbodyWidth = this.relTable.offsetWidth this.tbodyWidth = this.relTable.offsetWidth
this.headerRealEl = this.$refs.header.$el.querySelector('thead') this.headerRealEl = this.$refs.header.$el.querySelector('thead')
this.fixedLeftTBodyEl = this.$refs.fixedLeftTbody.$el
// console.log(this.wrapperWidth, this.tbodyWidth) // console.log(this.wrapperWidth, this.tbodyWidth)
this.init() this.init()
@ -408,6 +461,17 @@ export default {
// window.removeEventListener('resize', this.init) // window.removeEventListener('resize', this.init)
}, },
methods: { methods: {
onBodyScrolll (event) {
this.headerRealEl.style.transform = `translate3d(-${event.target.scrollLeft}px,0,0)`
if (this.fixedLeftTBodyEl) {
this.fixedLeftTBodyEl.scrollTop = event.target.scrollTop
}
console.log(
'TCL: onBodyScrolll -> event.target.scrollTop',
event.target.scrollTop
)
event.stopPropagation()
},
initData () { initData () {
this.copyData = this.data.slice(0).map((row, idx) => { this.copyData = this.data.slice(0).map((row, idx) => {
return { return {
@ -421,29 +485,6 @@ export default {
const ref = this.$refs['sorter_' + column.key][0] const ref = this.$refs['sorter_' + column.key][0]
ref.changeSort() ref.changeSort()
}, },
computeAlign (column) {
if (column.align) {
return {
'text-align': column.align
}
}
},
computeTdClass (column, params) {
let className = []
if (column.ellipsis) {
className.push('n-advanced-table__td-text--ellipsis')
}
if (!column.className) {
return className
}
if (typeof column.className === 'string') {
className.push(column.className)
} else if (typeof column.className === 'function') {
className.push(column.className(params))
}
// console.log(className)
return className
},
clearSelect () { clearSelect () {
this.$nextTick(() => { this.$nextTick(() => {
this.checkBoxes = [] this.checkBoxes = []
@ -477,12 +518,7 @@ export default {
*/ */
setParams ({ filter, sorter, page, searcher }) { setParams ({ filter, sorter, page, searcher }) {
if (sorter) { if (sorter) {
// console.log('this.sortIndexs', this.sortIndexs)
this.$set(this.sortIndexs, sorter.key, sorter.type) this.$set(this.sortIndexs, sorter.key, sorter.type)
// this.sortIndexs[sorter.key] = sorter.type
// const ref = this.$refs['sorter_' + sorter.key][0]
// ref.setSort(sorter.type)
// this.sortIndexs[sorter.key] = sorter.type
} else { } else {
// clear // clear
this.clearSort() this.clearSort()
@ -525,13 +561,6 @@ export default {
}) })
this.currentSortColumn = null this.currentSortColumn = null
}, },
onBodyScrolll (event) {
this.headerRealEl.style.transform = `translate3d(-${event.target.scrollLeft}px,0,0)`
// this.$refs.header.$el.scrollLeft = event.target.scrollLeft
event.stopPropagation()
},
computeScollBar () { computeScollBar () {
this.$nextTick(() => { this.$nextTick(() => {
this.tbodyWidth = this.relTable.offsetWidth this.tbodyWidth = this.relTable.offsetWidth
@ -539,24 +568,6 @@ export default {
// console.log('TCL: mounted -> this.scrollBarWidth', this.wrapperWidth, this.tbodyWidth) // console.log('TCL: mounted -> this.scrollBarWidth', this.wrapperWidth, this.tbodyWidth)
}) })
}, },
computeCustomWidthStl (column) {
if (column.width) {
let width = column.width
return {
width: width + 'px',
'padding-right': this.scrollBarWidth + 'px'
// minWidth: width + 'px'
}
} else if (column.type === 'selection') {
let width = 60
return {
width: width + 'px',
'padding-right': this.scrollBarWidth + 'px'
// minWidth: width + 'px'
}
}
return null
},
computePageDivideData (data) { computePageDivideData (data) {
if (this.pagination && this.pagination.limit && !this.pagination.custom) { if (this.pagination && this.pagination.limit && !this.pagination.custom) {
let start = (this.currentPage - 1) * this.pagination.limit let start = (this.currentPage - 1) * this.pagination.limit

View File

@ -1,7 +1,21 @@
@import "./mixins/mixins.scss"; @import './mixins/mixins.scss';
@import "./themes/vars.scss"; @import './themes/vars.scss';
@include themes-mixin { @include themes-mixin {
.n-advance-table__fixed--left {
display: inline-block;
position: absolute;
z-index: 100;
// box-shadow: 10px 0 16px 3px rgba(0, 0, 0, 0.2);
.n-table {
width: auto;
box-shadow: none;
border-radius: 0;
}
table {
width: auto;
}
}
@include b(advance-table--col-border) { @include b(advance-table--col-border) {
table { table {
thead { thead {
@ -102,6 +116,7 @@
@include e(tbody) { @include e(tbody) {
box-shadow: $--table-box-shadow; box-shadow: $--table-box-shadow;
border: $--table-border; border: $--table-border;
position: relative;
} }
@include b(table) { @include b(table) {
&::-webkit-scrollbar-thumb { &::-webkit-scrollbar-thumb {