mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2024-12-27 05:00:48 +08:00
294 lines
7.4 KiB
Vue
294 lines
7.4 KiB
Vue
<!--
|
|
* @Author: Volankey@gmail.com
|
|
* @Company: Tusimple
|
|
* @Date: 2019-10-23 16:06:59
|
|
* @LastEditors: Jiwen.bai
|
|
* @LastEditTime: 2019-11-07 16:17:14
|
|
-->
|
|
<template>
|
|
<!-- table body -->
|
|
<div
|
|
ref="scrollContainer"
|
|
class="n-table n-advance-table__body"
|
|
:class="{
|
|
[`n-${synthesizedTheme}-theme`]: synthesizedTheme
|
|
}"
|
|
:style="computeTbodyStl"
|
|
style="border-top-left-radius:0;border-top-right-radius:0;box-sizing: border-box;"
|
|
@scroll="onBodyScrolll"
|
|
@mouseenter="onMouseEnter"
|
|
@mouseleave="onMouseLeave"
|
|
>
|
|
<table ref="scrollContent" cellspacing="0">
|
|
<colgroup>
|
|
<col
|
|
v-for="(column, i) in columns"
|
|
:key="i"
|
|
:style="computeCustomWidthStl(column)"
|
|
>
|
|
</colgroup>
|
|
<tbody>
|
|
<template v-if="showingData.length === 0">
|
|
<n-tr>
|
|
<n-td v-for="column in columns" :key="column.key" />
|
|
</n-tr>
|
|
</template>
|
|
<n-tr
|
|
v-for="(rowData, i) in showingData"
|
|
:key="i"
|
|
:style="computeTrStl"
|
|
:class="
|
|
typeof rowClassName === 'function'
|
|
? rowClassName(rowData, i)
|
|
: rowClassName
|
|
"
|
|
@mouseenter.native="e => onRowHover(e, rowData, i)"
|
|
@mouseleave.native="e => onRowLeave(e, rowData, i)"
|
|
>
|
|
<template v-for="column in columns">
|
|
<n-td
|
|
:key="column.key"
|
|
:style="computeAlign(column)"
|
|
:class="computeTdClass(column, rowData)"
|
|
>
|
|
<!-- 批量选择 -->
|
|
<n-checkbox
|
|
v-if="
|
|
column.type === 'selection' &&
|
|
(column.disabled && !column.disabled(rowData, i))
|
|
"
|
|
v-model="checkBoxes[rowData._index]"
|
|
/>
|
|
<n-checkbox
|
|
v-else-if="
|
|
column.type === 'selection' &&
|
|
(column.disabled && column.disabled(rowData, i))
|
|
"
|
|
v-model="disabledCheckBox[rowData._index]"
|
|
:disabled="!(disabledCheckBox[rowData._index] = false)"
|
|
/>
|
|
<n-checkbox
|
|
v-else-if="column.type === 'selection'"
|
|
v-model="checkBoxes[rowData._index]"
|
|
/>
|
|
<row
|
|
v-else
|
|
:index="i"
|
|
:row="rowData"
|
|
:key-name="column.key"
|
|
:render="column.render"
|
|
:column="column"
|
|
/>
|
|
</n-td>
|
|
</template>
|
|
</n-tr>
|
|
</tbody>
|
|
<!-- <div
|
|
v-if="scrollBarHorizontalHeight"
|
|
class="n-advance-table-scroll-bar-placeholder"
|
|
:style="{ height: scrollBarHorizontalHeight + 'px' }"
|
|
/> -->
|
|
</table>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import row from '../row/index.js'
|
|
import { addClass, removeClass } from '../utils'
|
|
import { storageMixin } from '../store'
|
|
import withapp from '../../../mixins/withapp'
|
|
import themeable from '../../../mixins/themeable'
|
|
// import NScrollbar from '../../Scrollbar'
|
|
|
|
export default {
|
|
components: {
|
|
// NScrollbar,
|
|
row
|
|
},
|
|
mixins: [ withapp, themeable, storageMixin ],
|
|
props: {
|
|
fixed: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
trHeight: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
minHeight: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
height: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
tbodyWrapperOffsetHeight: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
scrollBarHorizontalHeight: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
scrollBarVerticalWidth: {
|
|
type: [Number, String],
|
|
default: 0
|
|
},
|
|
tableStl: {
|
|
type: Object,
|
|
default: () => ({})
|
|
},
|
|
showingData: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
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 () {
|
|
return {}
|
|
},
|
|
computed: {
|
|
computeTrStl () {
|
|
return {
|
|
height: this.trHeight ? this.trHeight + 'px' : null
|
|
}
|
|
},
|
|
computeTbodyStl () {
|
|
if (this.fixed && this.height) {
|
|
return Object.assign({}, this.tableStl, {
|
|
height: this.height + 'px',
|
|
minHeight: this.minHeight + 'px',
|
|
marginRight: this.scrollBarVerticalWidth
|
|
? -this.scrollBarVerticalWidth + 'px'
|
|
: null
|
|
})
|
|
} else {
|
|
return this.tableStl
|
|
}
|
|
}
|
|
},
|
|
watch: {
|
|
'$tableStore.state.currentHoverRow' (index, oldIndex) {
|
|
const hoverClassName = 'n-table__tr--hover'
|
|
const rowsDom = this.$el.querySelectorAll('table tr')
|
|
const oldRowDom = rowsDom[oldIndex]
|
|
const newRowDom = rowsDom[index]
|
|
window.requestAnimationFrame(() => {
|
|
if (oldRowDom) {
|
|
removeClass(oldRowDom, hoverClassName)
|
|
}
|
|
if (newRowDom) {
|
|
addClass(newRowDom, hoverClassName)
|
|
}
|
|
})
|
|
}
|
|
},
|
|
mounted () {
|
|
if (this.headerRefName) {
|
|
let headerRef = this.$parent.$refs[this.headerRefName]
|
|
this.headerRealEl = headerRef.$el.querySelector('thead')
|
|
}
|
|
},
|
|
methods: {
|
|
getScrollContainer () {
|
|
return this.$refs.scrollContainer || null
|
|
},
|
|
getScrollContent () {
|
|
return this.$refs.scrollContent || null
|
|
},
|
|
onMouseEnter (e) {
|
|
this.$tableStore.commit('currentTableEl', e.currentTarget)
|
|
},
|
|
onMouseLeave (e) {
|
|
this.$tableStore.commit('currentTableEl', null)
|
|
},
|
|
onRowHover (e, rowData, index) {
|
|
this.$tableStore.commit('currentHoverRow', index)
|
|
},
|
|
onRowLeave (e, rowData) {
|
|
this.$tableStore.commit('currentHoverRow', null)
|
|
},
|
|
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
|
|
},
|
|
computeAlign (column) {
|
|
if (column.align) {
|
|
return {
|
|
'text-align': column.align
|
|
}
|
|
}
|
|
},
|
|
|
|
computeTdClass (column, params) {
|
|
let className = {}
|
|
if (column.fixed) {
|
|
className['n-advance-table__td--fixed'] = true
|
|
}
|
|
if (column.ellipsis) {
|
|
className['n-advance-table__td-text'] = true
|
|
className['n-advance-table__td-text--ellipsis'] = true
|
|
|
|
// 'n-advance-table__td-text': true,
|
|
// 'n-advance-table__td-text--ellipsis': column.ellipsis
|
|
}
|
|
if (!column.className) {
|
|
return className
|
|
}
|
|
if (typeof column.className === 'string') {
|
|
className[column.className] = true
|
|
} else if (typeof column.className === 'function') {
|
|
column.className(column, params).forEach(name => {
|
|
className[name] = true
|
|
})
|
|
}
|
|
// console.log(className)
|
|
return className
|
|
},
|
|
onBodyScrolll (event) {
|
|
this.$emit('on-scroll', event)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style></style>
|