mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
fix(components): [table] revert 20210 (#21482)
* fix(components): [table] revert 20210 * chore: update * test: check indent
This commit is contained in:
@@ -282,7 +282,7 @@ table/tooltip-formatter
|
||||
| row-key | key of row data, used for optimizing rendering. Required if `reserve-selection` is on or display tree data. When its type is String, multi-level access is supported, e.g. `user.info.id`, but `user.info[0].id` is not supported, in which case `Function` should be used | ^[function]`(row: any) => string` / ^[string] | — |
|
||||
| empty-text | displayed text when data is empty. You can customize this area with `#empty` | ^[string] | No Data |
|
||||
| default-expand-all | whether expand all rows by default, works when the table has a column type="expand" or contains tree structure data | ^[boolean] | false |
|
||||
| expand-row-keys | set expanded rows by this prop, prop's value is the keys of expand rows, you should set row-key before using this prop. starting from version ^(2.10.3), keys of type number are supported. | ^[object]`Array<string \| number>` | — |
|
||||
| expand-row-keys | set expanded rows by this prop, prop's value is the keys of expand rows, you should set row-key before using this prop. | ^[object]`Array<string>` | — |
|
||||
| default-sort | set the default sort column and order. property `prop` is used to set default sort column, property `order` is used to set default sort order | ^[object]`Sort` | if `prop` is set, and `order` is not set, then `order` is default to ascending |
|
||||
| tooltip-effect | the `effect` of the overflow tooltip | ^[enum]`'dark' \| 'light'` | dark |
|
||||
| tooltip-options ^(2.2.28) | the options for the overflow tooltip, [see the following tooltip component](tooltip.html#attributes) | ^[object]`Pick<ElTooltipProps, 'effect' \| 'enterable' \| 'hideAfter' \| 'offset' \| 'placement' \| 'popperClass' \| 'popperOptions' \| 'showAfter' \| 'showArrow'>` | ^[object]`{ enterable: true, placement: 'top', showArrow: true, hideAfter: 200, popperOptions: { strategy: 'fixed' } }` |
|
||||
|
||||
@@ -63,79 +63,6 @@ export function getTestData() {
|
||||
]
|
||||
}
|
||||
|
||||
export function getTestDataNumAndString() {
|
||||
return [
|
||||
{
|
||||
id: 1,
|
||||
test: {
|
||||
id: 1,
|
||||
},
|
||||
name: 'Toy Story',
|
||||
release: '1995-11-22',
|
||||
director: 'John Lasseter',
|
||||
runtime: 80,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
test: {
|
||||
id: 2,
|
||||
},
|
||||
name: 'Toy Story 2',
|
||||
release: '1999-11-24',
|
||||
director: 'John Lasseter',
|
||||
runtime: 92,
|
||||
children: [
|
||||
{
|
||||
id: 21,
|
||||
test: {
|
||||
id: 21,
|
||||
},
|
||||
key: '2asdf-21',
|
||||
name: 'Toy Story 2',
|
||||
release: '1999-11-24',
|
||||
director: 'John Lasseter',
|
||||
runtime: 92,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
test: {
|
||||
id: 3,
|
||||
},
|
||||
name: 'Monsters, Inc.',
|
||||
release: '2001-11-2',
|
||||
director: 'Peter Docter',
|
||||
runtime: 92,
|
||||
children: [
|
||||
{
|
||||
id: '31',
|
||||
test: {
|
||||
id: '31',
|
||||
},
|
||||
name: 'Monsters, Inc.',
|
||||
release: '2001-11-2',
|
||||
director: 'Peter Docter',
|
||||
runtime: 92,
|
||||
children: [
|
||||
{
|
||||
id: 311,
|
||||
test: {
|
||||
id: 311,
|
||||
},
|
||||
key: '2asdf-21',
|
||||
name: 'Toy Story 2',
|
||||
release: '1999-11-24',
|
||||
director: 'John Lasseter',
|
||||
runtime: 92,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
export function getMultiRowTestData() {
|
||||
return [
|
||||
{
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
doubleWait,
|
||||
getMultiRowTestData,
|
||||
getTestData,
|
||||
getTestDataNumAndString,
|
||||
mount,
|
||||
} from './table-test-common'
|
||||
|
||||
@@ -1722,6 +1721,14 @@ describe('Table.vue', () => {
|
||||
expect(wrapper.findAll('.el-table__row').length).toEqual(8)
|
||||
expect(spy.mock.calls[0][0]).toBeInstanceOf(Object)
|
||||
expect(spy.mock.calls[0][1]).toBeTruthy()
|
||||
|
||||
const iconTr = expandIcon.element.closest('tr')
|
||||
expect(iconTr.classList).toContain('el-table__row--level-0')
|
||||
const firstChildRow = iconTr.nextElementSibling
|
||||
expect(firstChildRow.classList).toContain('el-table__row--level-1')
|
||||
const indent = firstChildRow.querySelector('.el-table__indent')
|
||||
expect(indent).toBeTruthy()
|
||||
expect(indent.style.paddingLeft).toEqual('16px')
|
||||
})
|
||||
|
||||
it('tree-props & default-expand-all with dynamic data', async () => {
|
||||
@@ -1948,72 +1955,6 @@ describe('Table.vue', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('expand-row-keys number and string', async () => {
|
||||
wrapper = mount({
|
||||
components: {
|
||||
ElTable,
|
||||
ElTableColumn,
|
||||
},
|
||||
template: `
|
||||
<el-table :data="testData" row-key="id" :expand-row-keys="[2, 3, '31']">
|
||||
<el-table-column prop="name" label="片名" />
|
||||
<el-table-column prop="release" label="发行日期" />
|
||||
<el-table-column prop="director" label="导演" />
|
||||
<el-table-column prop="runtime" label="时长(分)" />
|
||||
</el-table>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
testData: getTestDataNumAndString(),
|
||||
}
|
||||
},
|
||||
})
|
||||
await doubleWait()
|
||||
// 查找所有 level-1 的行
|
||||
const level1Rows = wrapper.findAll('.el-table__row--level-1')
|
||||
|
||||
// 遍历每一行并检查其样式是否不为 display: none;
|
||||
level1Rows.forEach((row) => {
|
||||
const rowStyle = row.attributes('style')
|
||||
if (rowStyle) {
|
||||
expect(rowStyle).not.toContain('display: none;') // 期望样式不包含 display: none;
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('expand-row-keys multi-level number and string', async () => {
|
||||
wrapper = mount({
|
||||
components: {
|
||||
ElTable,
|
||||
ElTableColumn,
|
||||
},
|
||||
template: `
|
||||
<el-table :data="testData" row-key="test.id" :expand-row-keys="[2, 3, '31']">
|
||||
<el-table-column prop="name" label="片名" />
|
||||
<el-table-column prop="release" label="发行日期" />
|
||||
<el-table-column prop="director" label="导演" />
|
||||
<el-table-column prop="runtime" label="时长(分)" />
|
||||
</el-table>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
testData: getTestDataNumAndString(),
|
||||
}
|
||||
},
|
||||
})
|
||||
await doubleWait()
|
||||
// 查找所有 level-1 的行
|
||||
const level1Rows = wrapper.findAll('.el-table__row--level-1')
|
||||
|
||||
// 遍历每一行并检查其样式是否不为 display: none;
|
||||
level1Rows.forEach((row) => {
|
||||
const rowStyle = row.attributes('style')
|
||||
if (rowStyle) {
|
||||
expect(rowStyle).not.toContain('display: none;') // 期望样式不包含 display: none;
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('v-if on el-table-column should patch correctly', async () => {
|
||||
wrapper = mount({
|
||||
components: {
|
||||
|
||||
@@ -12,7 +12,7 @@ export interface TreeData extends TreeNode {
|
||||
}
|
||||
|
||||
function useTree<T extends DefaultRow>(watcherData: WatcherPropsData<T>) {
|
||||
const expandRowKeys = ref<Array<string | number>>([])
|
||||
const expandRowKeys = ref<Array<string>>([])
|
||||
const treeData = ref<Record<string, TreeData>>({})
|
||||
const indent = ref(16)
|
||||
const lazy = ref(false)
|
||||
@@ -49,23 +49,23 @@ function useTree<T extends DefaultRow>(watcherData: WatcherPropsData<T>) {
|
||||
|
||||
const normalize = (data: T[]) => {
|
||||
const rowKey = watcherData.rowKey.value
|
||||
const res = new Map<string | number, TreeData>() // 使用 Map 替代 Object,解决 number key 的问题
|
||||
const res = {} as Record<string, TreeData>
|
||||
walkTreeNode(
|
||||
data,
|
||||
(parent, children, level) => {
|
||||
const parentId = getRowIdentity(parent, rowKey, true)
|
||||
const parentId = getRowIdentity(parent, rowKey)
|
||||
if (isArray(children)) {
|
||||
res.set(parentId, {
|
||||
children: children.map((row) => row[rowKey!]),
|
||||
res[parentId] = {
|
||||
children: children.map((row) => getRowIdentity(row, rowKey)),
|
||||
level,
|
||||
})
|
||||
}
|
||||
} else if (lazy.value) {
|
||||
// 当 children 不存在且 lazy 为 true,该节点即为懒加载的节点
|
||||
res.set(parentId, {
|
||||
res[parentId] = {
|
||||
children: [],
|
||||
lazy: true,
|
||||
level,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
childrenColumnName.value,
|
||||
@@ -82,8 +82,9 @@ function useTree<T extends DefaultRow>(watcherData: WatcherPropsData<T>) {
|
||||
ifExpandAll ||= instance.store?.states.defaultExpandAll.value
|
||||
const nested = normalizedData.value
|
||||
const normalizedLazyNode_ = normalizedLazyNode.value
|
||||
const keys = Object.keys(nested)
|
||||
const newTreeData: Record<string, TreeData> = {}
|
||||
if (nested instanceof Map && nested.size) {
|
||||
if (keys.length) {
|
||||
const oldTreeData = unref(treeData)
|
||||
const rootLazyRowKeys: string[] = []
|
||||
const getExpanded = (oldValue: TreeData, key: string) => {
|
||||
@@ -101,9 +102,9 @@ function useTree<T extends DefaultRow>(watcherData: WatcherPropsData<T>) {
|
||||
}
|
||||
}
|
||||
// 合并 expanded 与 display,确保数据刷新后,状态不变
|
||||
nested.forEach((_, key) => {
|
||||
keys.forEach((key) => {
|
||||
const oldValue = oldTreeData[key]
|
||||
const newValue = { ...nested.get(key) }
|
||||
const newValue = { ...nested[key] }
|
||||
newValue.expanded = getExpanded(oldValue, key)
|
||||
if (newValue.lazy) {
|
||||
const { loaded = false, loading = false } = oldValue || {}
|
||||
@@ -163,7 +164,7 @@ function useTree<T extends DefaultRow>(watcherData: WatcherPropsData<T>) {
|
||||
}
|
||||
)
|
||||
|
||||
const updateTreeExpandKeys = (value: (string | number)[]) => {
|
||||
const updateTreeExpandKeys = (value: string[]) => {
|
||||
expandRowKeys.value = value
|
||||
updateTreeData()
|
||||
}
|
||||
|
||||
@@ -508,7 +508,7 @@ function useWatcher<T extends DefaultRow>() {
|
||||
rowKey,
|
||||
})
|
||||
// 适配层,expand-row-keys 在 Expand 与 TreeTable 中都有使用
|
||||
const setExpandRowKeysAdapter = (val: (string | number)[]) => {
|
||||
const setExpandRowKeysAdapter = (val: string[]) => {
|
||||
// 这里会触发额外的计算,但为了兼容性,暂时这么做
|
||||
setExpandRowKeys(val)
|
||||
updateTreeExpandKeys(val)
|
||||
|
||||
@@ -129,7 +129,7 @@ interface TableProps<T extends DefaultRow> {
|
||||
highlightCurrentRow?: boolean
|
||||
currentRowKey?: string | number
|
||||
emptyText?: string
|
||||
expandRowKeys?: Array<string | number>
|
||||
expandRowKeys?: Array<string>
|
||||
defaultExpandAll?: boolean
|
||||
defaultSort?: Sort
|
||||
tooltipEffect?: string
|
||||
|
||||
@@ -182,13 +182,12 @@ export const getColumnByCell = function <T extends DefaultRow>(
|
||||
|
||||
export const getRowIdentity = <T extends DefaultRow>(
|
||||
row: T,
|
||||
rowKey: string | ((row: T) => string) | null,
|
||||
isReturnRawValue: boolean = false
|
||||
rowKey: string | ((row: T) => string) | null
|
||||
): string => {
|
||||
if (!row) throw new Error('Row is required when get row identity')
|
||||
if (isString(rowKey)) {
|
||||
if (!rowKey.includes('.')) {
|
||||
return isReturnRawValue ? row[rowKey] : `${row[rowKey]}`
|
||||
return `${row[rowKey]}`
|
||||
}
|
||||
const key = rowKey.split('.')
|
||||
let current: any = row
|
||||
@@ -197,7 +196,7 @@ export const getRowIdentity = <T extends DefaultRow>(
|
||||
}
|
||||
//TODO: "current" is now any, we just satisfies typecheck here
|
||||
// but this function can actually return a number
|
||||
return isReturnRawValue ? (current as string) : `${current}`
|
||||
return `${current}`
|
||||
} else if (isFunction(rowKey)) {
|
||||
return rowKey.call(null, row)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user