mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
* refactor(style): Update Eslint to V9 and Prettier to V3 * fix: vscode color * fix: vscode color * chore: remove Useless dependence and old config file * chore: format * Merge branch 'dev' into eslintV9 * fix: fix * fix: ssr test * fix: ssr test * fix: use defineConfig * fix: prettier format and ignore docs dist * fix: index.mjs => index.js * fix: Vscode color * fix: prettier ignore global.d.ts * fix: format --------- Co-authored-by: 2586740555 <15972343+CYJ090915@user.noreply.gitee.com>
221 lines
6.4 KiB
TypeScript
221 lines
6.4 KiB
TypeScript
import {
|
|
Fragment,
|
|
computed,
|
|
defineComponent,
|
|
getCurrentInstance,
|
|
h,
|
|
onBeforeMount,
|
|
onBeforeUnmount,
|
|
onMounted,
|
|
ref,
|
|
} from 'vue'
|
|
import ElCheckbox from '@element-plus/components/checkbox'
|
|
import { isArray, isString, isUndefined } from '@element-plus/utils'
|
|
import { cellStarts } from '../config'
|
|
import { compose, mergeOptions } from '../util'
|
|
import useWatcher from './watcher-helper'
|
|
import useRender from './render-helper'
|
|
import defaultProps from './defaults'
|
|
|
|
import type { VNode } from 'vue'
|
|
import type { TableColumn, TableColumnCtx } from './defaults'
|
|
import type { DefaultRow } from '../table/defaults'
|
|
|
|
let columnIdSeed = 1
|
|
|
|
//TODO: when vue 3.3 we can set this component a generic: https://github.com/vuejs/core/pull/7963
|
|
export default defineComponent({
|
|
name: 'ElTableColumn',
|
|
components: {
|
|
ElCheckbox,
|
|
},
|
|
props: defaultProps,
|
|
setup(props, { slots }) {
|
|
const instance = getCurrentInstance() as TableColumn<DefaultRow>
|
|
const columnConfig = ref<Partial<TableColumnCtx<DefaultRow>>>({})
|
|
const owner = computed(() => {
|
|
let parent = instance.parent as any
|
|
while (parent && !parent.tableId) {
|
|
parent = parent.parent
|
|
}
|
|
return parent
|
|
})
|
|
|
|
const { registerNormalWatchers, registerComplexWatchers } = useWatcher(
|
|
owner,
|
|
props
|
|
)
|
|
const {
|
|
columnId,
|
|
isSubColumn,
|
|
realHeaderAlign,
|
|
columnOrTableParent,
|
|
setColumnWidth,
|
|
setColumnForcedProps,
|
|
setColumnRenders,
|
|
getPropsData,
|
|
getColumnElIndex,
|
|
realAlign,
|
|
updateColumnOrder,
|
|
} = useRender(props as unknown as TableColumnCtx<DefaultRow>, slots, owner)
|
|
|
|
const parent = columnOrTableParent.value
|
|
columnId.value = `${
|
|
('tableId' in parent && parent.tableId) ||
|
|
('columnId' in parent && parent.columnId)
|
|
}_column_${columnIdSeed++}`
|
|
onBeforeMount(() => {
|
|
isSubColumn.value = owner.value !== parent
|
|
|
|
const type = (props.type as keyof typeof cellStarts) || 'default'
|
|
const sortable = props.sortable === '' ? true : props.sortable
|
|
//The selection column should not be affected by `showOverflowTooltip`.
|
|
const showOverflowTooltip =
|
|
type === 'selection'
|
|
? false
|
|
: isUndefined(props.showOverflowTooltip)
|
|
? parent.props.showOverflowTooltip
|
|
: props.showOverflowTooltip
|
|
const tooltipFormatter = isUndefined(props.tooltipFormatter)
|
|
? parent.props.tooltipFormatter
|
|
: props.tooltipFormatter
|
|
const defaults = {
|
|
...cellStarts[type],
|
|
id: columnId.value,
|
|
type,
|
|
property: props.prop || props.property,
|
|
align: realAlign,
|
|
headerAlign: realHeaderAlign,
|
|
showOverflowTooltip,
|
|
tooltipFormatter,
|
|
// filter 相关属性
|
|
filterable: props.filters || props.filterMethod,
|
|
filteredValue: [],
|
|
filterPlacement: '',
|
|
filterClassName: '',
|
|
isColumnGroup: false,
|
|
isSubColumn: false,
|
|
filterOpened: false,
|
|
// sort 相关属性
|
|
sortable,
|
|
// index 列
|
|
index: props.index,
|
|
// <el-table-column key="xxx" />
|
|
rawColumnKey: instance.vnode.key,
|
|
}
|
|
|
|
const basicProps = [
|
|
'columnKey',
|
|
'label',
|
|
'className',
|
|
'labelClassName',
|
|
'type',
|
|
'renderHeader',
|
|
'formatter',
|
|
'fixed',
|
|
'resizable',
|
|
]
|
|
const sortProps = ['sortMethod', 'sortBy', 'sortOrders']
|
|
const selectProps = ['selectable', 'reserveSelection']
|
|
const filterProps = [
|
|
'filterMethod',
|
|
'filters',
|
|
'filterMultiple',
|
|
'filterOpened',
|
|
'filteredValue',
|
|
'filterPlacement',
|
|
'filterClassName',
|
|
]
|
|
|
|
let column = getPropsData(basicProps, sortProps, selectProps, filterProps)
|
|
|
|
column = mergeOptions(defaults, column)
|
|
// 注意 compose 中函数执行的顺序是从右到左
|
|
const chains = compose(
|
|
setColumnRenders,
|
|
setColumnWidth,
|
|
setColumnForcedProps
|
|
)
|
|
column = chains(column) as unknown as TableColumnCtx<DefaultRow>
|
|
columnConfig.value = column
|
|
|
|
// 注册 watcher
|
|
registerNormalWatchers()
|
|
registerComplexWatchers()
|
|
})
|
|
onMounted(() => {
|
|
const parent = columnOrTableParent.value
|
|
const children = isSubColumn.value
|
|
? parent.vnode.el?.children
|
|
: parent.refs.hiddenColumns?.children
|
|
const getColumnIndex = () =>
|
|
getColumnElIndex(children || [], instance.vnode.el)
|
|
columnConfig.value.getColumnIndex = getColumnIndex
|
|
const columnIndex = getColumnIndex()
|
|
columnIndex > -1 &&
|
|
owner.value.store.commit(
|
|
'insertColumn',
|
|
columnConfig.value,
|
|
isSubColumn.value
|
|
? 'columnConfig' in parent && parent.columnConfig.value
|
|
: null,
|
|
updateColumnOrder
|
|
)
|
|
})
|
|
onBeforeUnmount(() => {
|
|
const getColumnIndex = columnConfig.value.getColumnIndex
|
|
const columnIndex = getColumnIndex ? getColumnIndex() : -1
|
|
columnIndex > -1 &&
|
|
owner.value.store.commit(
|
|
'removeColumn',
|
|
columnConfig.value,
|
|
isSubColumn.value
|
|
? 'columnConfig' in parent && parent.columnConfig.value
|
|
: null,
|
|
updateColumnOrder
|
|
)
|
|
})
|
|
instance.columnId = columnId.value
|
|
|
|
instance.columnConfig = columnConfig as any
|
|
return
|
|
},
|
|
render() {
|
|
try {
|
|
const renderDefault = this.$slots.default?.({
|
|
row: {},
|
|
column: {},
|
|
$index: -1,
|
|
})
|
|
const children = []
|
|
if (isArray(renderDefault)) {
|
|
for (const childNode of renderDefault) {
|
|
if (
|
|
(childNode.type as any)?.name === 'ElTableColumn' ||
|
|
childNode.shapeFlag & 2
|
|
) {
|
|
children.push(childNode)
|
|
} else if (
|
|
childNode.type === Fragment &&
|
|
isArray(childNode.children)
|
|
) {
|
|
childNode.children.forEach((vnode) => {
|
|
// No rendering when vnode is dynamic slot or text
|
|
if (
|
|
(vnode as VNode)?.patchFlag !== 1024 &&
|
|
!isString((vnode as VNode)?.children)
|
|
) {
|
|
children.push(vnode)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
const vnode = h('div', children)
|
|
return vnode
|
|
} catch {
|
|
return h('div', [])
|
|
}
|
|
},
|
|
})
|