Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
水玉婷
ai-wechat
Commits
f845f8b0
Commit
f845f8b0
authored
Mar 27, 2026
by
水玉婷
Browse files
feat:表格添加多列排序功能
parent
1f5f143c
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/views/components/TableComponent.vue
View file @
f845f8b0
...
@@ -34,7 +34,7 @@
...
@@ -34,7 +34,7 @@
</template>
</template>
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
computed
,
ref
}
from
'
vue
'
;
import
{
computed
,
ref
,
reactive
}
from
'
vue
'
;
import
{
Table
as
ATable
}
from
'
ant-design-vue
'
;
import
{
Table
as
ATable
}
from
'
ant-design-vue
'
;
import
{
formatNumber
}
from
'
./utils/utils
'
;
import
{
formatNumber
}
from
'
./utils/utils
'
;
...
@@ -47,6 +47,12 @@ const paginationState = ref({
...
@@ -47,6 +47,12 @@ const paginationState = ref({
pageSize
:
15
pageSize
:
15
});
});
// 排序状态
const
sortState
=
reactive
({
sortedData
:
[]
as
any
[],
isSorted
:
false
});
// 处理表格变化事件(包括分页、排序等)
// 处理表格变化事件(包括分页、排序等)
const
handleTableChange
=
(
pagination
:
any
,
filters
:
any
,
sorter
:
any
)
=>
{
const
handleTableChange
=
(
pagination
:
any
,
filters
:
any
,
sorter
:
any
)
=>
{
// 处理分页变化
// 处理分页变化
...
@@ -58,9 +64,75 @@ const handleTableChange = (pagination: any, filters: any, sorter: any) => {
...
@@ -58,9 +64,75 @@ const handleTableChange = (pagination: any, filters: any, sorter: any) => {
};
};
}
}
//
可以在这里添加排序变化的处理
//
处理排序变化(支持多列排序)
if
(
sorter
)
{
if
(
sorter
)
{
// console.log('排序变化:', sorter);
// 更新排序状态
sortState
.
isSorted
=
true
;
// 获取原始数据
let
rawData
:
any
[]
=
[];
if
(
Array
.
isArray
(
props
.
tableData
.
rows
))
{
rawData
=
[...
props
.
tableData
.
rows
];
}
else
if
(
Array
.
isArray
(
props
.
tableData
))
{
rawData
=
[...
props
.
tableData
];
}
// 应用排序
if
(
Array
.
isArray
(
sorter
))
{
// 多列排序情况:按优先级顺序应用排序
sorter
.
forEach
((
sortItem
)
=>
{
if
(
sortItem
.
order
)
{
rawData
.
sort
((
a
,
b
)
=>
{
const
aValue
=
getSortableValue
(
a
,
sortItem
.
field
);
const
bValue
=
getSortableValue
(
b
,
sortItem
.
field
);
if
(
sortItem
.
order
===
'
ascend
'
)
{
return
aValue
-
bValue
;
}
else
{
return
bValue
-
aValue
;
}
});
}
});
}
else
if
(
sorter
.
order
)
{
// 单列排序情况
rawData
.
sort
((
a
,
b
)
=>
{
const
aValue
=
getSortableValue
(
a
,
sorter
.
field
);
const
bValue
=
getSortableValue
(
b
,
sorter
.
field
);
if
(
sorter
.
order
===
'
ascend
'
)
{
return
aValue
-
bValue
;
}
else
{
return
bValue
-
aValue
;
}
});
}
// 更新排序后的数据
sortState
.
sortedData
=
rawData
;
}
};
// 获取可排序的值(用于数字字段)
const
getSortableValue
=
(
item
:
any
,
field
:
string
)
=>
{
if
(
item
[
field
]
&&
typeof
item
[
field
]
===
'
object
'
&&
item
[
field
].
value
!==
undefined
)
{
// 对于特殊格式的数据,使用value字段进行排序
return
parseFloat
(
item
[
field
].
value
)
||
0
;
}
else
{
// 普通字段直接使用
return
parseFloat
(
item
[
field
])
||
0
;
}
};
// 获取字符串值(用于文字字段)
const
getStringValue
=
(
item
:
any
,
field
:
string
):
string
=>
{
if
(
item
[
field
]
&&
typeof
item
[
field
]
===
'
object
'
&&
item
[
field
].
display
!==
undefined
)
{
// 对于特殊格式的数据,使用display字段进行排序
return
String
(
item
[
field
].
display
||
''
);
}
else
{
// 普通字段直接使用
return
String
(
item
[
field
]
||
''
);
}
}
};
};
...
@@ -92,46 +164,58 @@ const props = withDefaults(defineProps<Props>(), {
...
@@ -92,46 +164,58 @@ const props = withDefaults(defineProps<Props>(), {
const
processedTableData
=
computed
(()
=>
{
const
processedTableData
=
computed
(()
=>
{
if
(
!
props
.
tableData
)
return
[];
if
(
!
props
.
tableData
)
return
[];
// 如果有排序后的数据,使用排序后的数据
if
(
sortState
.
isSorted
&&
sortState
.
sortedData
.
length
>
0
)
{
return
processRawData
(
sortState
.
sortedData
);
}
// 处理传入完整数据结构的情况
// 处理传入完整数据结构的情况
if
(
Array
.
isArray
(
props
.
tableData
.
rows
))
{
if
(
Array
.
isArray
(
props
.
tableData
.
rows
))
{
// 获取字段配置
return
processRawData
(
props
.
tableData
.
rows
);
const
indexFields
=
props
.
tableData
?.
indexFields
||
[];
const
dimFields
=
props
.
tableData
?.
dimFields
||
[];
const
indexFieldsFormat
=
props
.
tableData
?.
indexFieldsFormat
||
[];
// 需要显示的字段:dimFields + indexFields
const
fieldsToShow
=
[...
dimFields
,
...
indexFields
];
return
props
.
tableData
.
rows
.
map
(
row
=>
{
const
processedRow
:
Record
<
string
,
any
>
=
{};
// 处理每个字段
fieldsToShow
.
forEach
(
field
=>
{
if
(
row
.
hasOwnProperty
(
field
))
{
// 如果是indexFields字段,检查是否有对应的indexFieldsFormat字段
const
fieldIndex
=
indexFields
.
indexOf
(
field
);
if
(
fieldIndex
!==
-
1
&&
indexFieldsFormat
[
fieldIndex
]
&&
row
.
hasOwnProperty
(
indexFieldsFormat
[
fieldIndex
]))
{
// 使用indexFieldsFormat的格式化值来显示,但保留原始值用于排序
processedRow
[
field
]
=
{
display
:
row
[
indexFieldsFormat
[
fieldIndex
]],
value
:
row
[
field
]
};
}
else
{
// 其他字段直接使用原始值
processedRow
[
field
]
=
row
[
field
];
}
}
});
return
processedRow
;
});
}
else
if
(
Array
.
isArray
(
props
.
tableData
))
{
}
else
if
(
Array
.
isArray
(
props
.
tableData
))
{
return
props
.
tableData
;
return
processRawData
(
props
.
tableData
)
;
}
}
return
[];
return
[];
});
});
// 处理原始数据
const
processRawData
=
(
rawData
:
any
[])
=>
{
if
(
!
rawData
||
rawData
.
length
===
0
)
return
[];
// 获取字段配置
const
indexFields
=
props
.
tableData
?.
indexFields
||
[];
const
dimFields
=
props
.
tableData
?.
dimFields
||
[];
const
indexFieldsFormat
=
props
.
tableData
?.
indexFieldsFormat
||
[];
// 需要显示的字段:dimFields + indexFields
const
fieldsToShow
=
[...
dimFields
,
...
indexFields
];
return
rawData
.
map
((
row
:
any
)
=>
{
const
processedRow
:
Record
<
string
,
any
>
=
{};
// 处理每个字段
fieldsToShow
.
forEach
(
field
=>
{
if
(
row
.
hasOwnProperty
(
field
))
{
// 如果是indexFields字段,检查是否有对应的indexFieldsFormat字段
const
fieldIndex
=
indexFields
.
indexOf
(
field
);
if
(
fieldIndex
!==
-
1
&&
indexFieldsFormat
[
fieldIndex
]
&&
row
.
hasOwnProperty
(
indexFieldsFormat
[
fieldIndex
]))
{
// 使用indexFieldsFormat的格式化值来显示,但保留原始值用于排序
processedRow
[
field
]
=
{
display
:
row
[
indexFieldsFormat
[
fieldIndex
]],
value
:
row
[
field
]
};
}
else
{
// 其他字段直接使用原始值
processedRow
[
field
]
=
row
[
field
];
}
}
});
return
processedRow
;
});
};
// 判断列是否为数字列
// 判断列是否为数字列
const
isNumericColumn
=
(
header
:
string
)
=>
{
const
isNumericColumn
=
(
header
:
string
)
=>
{
// 使用indexFields来判断数字列
// 使用indexFields来判断数字列
...
@@ -190,18 +274,29 @@ const tableColumns = computed(() => {
...
@@ -190,18 +274,29 @@ const tableColumns = computed(() => {
width
:
getColumnWidth
(
header
),
width
:
getColumnWidth
(
header
),
ellipsis
:
true
,
ellipsis
:
true
,
...
fixedConfig
,
...
fixedConfig
,
sorter
:
isNumericColumn
(
header
)
?
(
a
,
b
)
=>
{
sorter
:
isSortColumn
(
header
)
?
{
// 对于indexFields字段,使用存储的原始值进行排序
compare
:
(
a
:
any
,
b
:
any
)
=>
{
if
(
isIndexField
&&
a
[
header
]
&&
a
[
header
].
value
!==
undefined
)
{
// 对于数字字段
const
aValue
=
parseFloat
(
a
[
header
].
value
);
if
(
isNumericColumn
(
header
))
{
const
bValue
=
parseFloat
(
b
[
header
].
value
);
// 对于indexFields字段,使用存储的原始值进行排序
return
aValue
-
bValue
;
if
(
isIndexField
&&
a
[
header
]
&&
a
[
header
].
value
!==
undefined
)
{
}
else
{
const
aValue
=
parseFloat
(
a
[
header
].
value
);
// 其他字段直接使用当前字段排序
const
bValue
=
parseFloat
(
b
[
header
].
value
);
const
aValue
=
parseFloat
(
a
[
header
]);
return
aValue
-
bValue
;
const
bValue
=
parseFloat
(
b
[
header
]);
}
else
{
return
aValue
-
bValue
;
// 其他数字字段直接使用当前字段排序
}
const
aValue
=
parseFloat
(
a
[
header
]);
const
bValue
=
parseFloat
(
b
[
header
]);
return
aValue
-
bValue
;
}
}
else
{
// 对于文字字段,使用字符串排序
const
aValue
=
getStringValue
(
a
,
header
);
const
bValue
=
getStringValue
(
b
,
header
);
return
aValue
.
localeCompare
(
bValue
,
'
zh-CN
'
);
}
},
multiple
:
1
// 所有列设置相同的优先级,测试排序行为
}
:
undefined
}
:
undefined
};
};
});
});
...
@@ -216,6 +311,12 @@ const isTextColumn = (header: string) => {
...
@@ -216,6 +311,12 @@ const isTextColumn = (header: string) => {
return
dimFields
.
includes
(
header
);
return
dimFields
.
includes
(
header
);
};
};
// 判断是否为可排序列(数字字段+文字字段里面包含名称的)
const
isSortColumn
=
(
header
:
string
):
boolean
=>
{
// 数字字段 或者 (文本字段且包含"名称")
return
isNumericColumn
(
header
)
||
(
isTextColumn
(
header
)
&&
header
.
toLowerCase
().
includes
(
'
名称
'
));
};
// 判断列是否为趋势列
// 判断列是否为趋势列
const
isTrendColumn
=
(
header
:
string
)
=>
{
const
isTrendColumn
=
(
header
:
string
)
=>
{
return
header
.
toLowerCase
().
includes
(
'
趋势
'
)
||
header
.
toLowerCase
().
includes
(
'
trend
'
);
return
header
.
toLowerCase
().
includes
(
'
趋势
'
)
||
header
.
toLowerCase
().
includes
(
'
trend
'
);
...
@@ -412,9 +513,8 @@ const getTableScroll = () => {
...
@@ -412,9 +513,8 @@ const getTableScroll = () => {
/* 表格样式 */
/* 表格样式 */
:deep
(
.ant-table
)
{
:deep
(
.ant-table
)
{
width
:
100%
;
width
:
100%
;
.ant-table-thead
>
tr
>
th
{
.ant-table-thead
>
tr
>
th
{
background
:
#D1E9FF
;
background
:
#D1E9FF
!important
;
color
:
#323232
;
color
:
#323232
;
font-weight
:
600
;
font-weight
:
600
;
padding
:
6px
8px
;
padding
:
6px
8px
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment