element-plus
Version:
A Component Library for Vue3.0
233 lines (229 loc) • 7 kB
text/typescript
import {
defineComponent,
getCurrentInstance,
computed,
onMounted,
nextTick,
ref,
h,
} from 'vue'
import ElCheckbox from '@element-plus/checkbox'
import FilterPanel from '../filter-panel.vue'
import useLayoutObserver from '../layout-observer'
import useEvent from './event-helper'
import useStyle from './style.helper'
import useUtils from './utils-helper'
import { hColgroup } from '../h-helper'
import { Table, TableHeader } from '../table.type'
import { TableHeaderProps } from './table-header'
export default defineComponent({
name: 'ElTableHeader',
components: {
ElCheckbox,
},
props: {
fixed: {
type: String,
default: '',
},
store: {
required: true,
type: Object,
},
border: Boolean,
defaultSort: {
type: Object,
default() {
return {
prop: '',
order: '',
}
},
},
},
setup(props: TableHeaderProps, { emit }) {
const instance = getCurrentInstance() as TableHeader
const parent = instance.parent as Table
const storeData = parent.store.states
const filterPanels = ref({})
const {
tableLayout,
onColumnsChange,
onScrollableChange,
} = useLayoutObserver(parent)
const hasGutter = computed(() => {
return !props.fixed && tableLayout.gutterWidth
})
onMounted(() => {
nextTick(() => {
const { prop, order } = props.defaultSort
const init = true
parent.store.commit('sort', { prop, order, init })
})
})
const {
handleHeaderClick,
handleHeaderContextMenu,
handleMouseDown,
handleMouseMove,
handleMouseOut,
handleSortClick,
handleFilterClick,
} = useEvent(props, emit)
const {
getHeaderRowStyle,
getHeaderRowClass,
getHeaderCellStyle,
getHeaderCellClass,
} = useStyle(props)
const { isGroup, toggleAllSelection, columnRows } = useUtils(props)
instance.state = {
onColumnsChange,
onScrollableChange,
}
// eslint-disable-next-line
instance.filterPanels = filterPanels
return {
columns: storeData.columns,
filterPanels,
hasGutter,
onColumnsChange,
onScrollableChange,
columnRows,
getHeaderRowClass,
getHeaderRowStyle,
getHeaderCellClass,
getHeaderCellStyle,
handleHeaderClick,
handleHeaderContextMenu,
handleMouseDown,
handleMouseMove,
handleMouseOut,
handleSortClick,
handleFilterClick,
isGroup,
toggleAllSelection,
}
},
render() {
return h(
'table',
{
border: '0',
cellpadding: '0',
cellspacing: '0',
class: 'el-table__header',
},
[
hColgroup(this.columns, this.hasGutter),
h(
'thead',
{
class: { 'is-group': this.isGroup, 'has-gutter': this.hasGutter },
},
this.columnRows.map((subColumns, rowIndex) =>
h(
'tr',
{
class: this.getHeaderRowClass(rowIndex),
key: rowIndex,
style: this.getHeaderRowStyle(rowIndex),
},
subColumns.map((column, cellIndex) =>
h(
'th',
{
class: this.getHeaderCellClass(
rowIndex,
cellIndex,
subColumns,
column,
),
colspan: column.colSpan,
key: `${column.id}-thead`,
rowSpan: column.rowSpan,
style: this.getHeaderCellStyle(
rowIndex,
cellIndex,
subColumns,
column,
),
onClick: $event => this.handleHeaderClick($event, column),
onContextmenu: $event =>
this.handleHeaderContextMenu($event, column),
onMousedown: $event => this.handleMouseDown($event, column),
onMouseMove: $event => this.handleMouseMove($event, column),
onMouseout: this.handleMouseOut,
},
[
h(
'div',
{
class: [
'cell',
column.filteredValue &&
column.filteredValue.length > 0
? 'highlight'
: '',
column.labelClassName,
],
},
[
column.renderHeader
? column.renderHeader({
column,
$index: cellIndex,
store: this.store,
_self: this.$parent,
})
: column.label,
column.sortable &&
h(
'span',
{
onClick: $event =>
this.handleSortClick($event, column),
class: 'caret-wrapper',
},
[
h('i', {
onClick: $event =>
this.handleSortClick(
$event,
column,
'ascending',
),
class: 'sort-caret ascending',
}),
h('i', {
onClick: $event =>
this.handleSortClick(
$event,
column,
'descending',
),
class: 'sort-caret descending',
}),
],
),
column.filterable &&
h(FilterPanel, {
store: this.$parent.store,
placement: column.filterPlacement || 'bottom-start',
column: column,
upDataColumn: (key, value) => {
column[key] = value
},
}),
],
),
],
),
),
),
),
),
],
)
},
})