@@ -7,6 +7,7 @@ import { cn } from '@/lib/utils'
77import type { Column , Table } from ' @tanstack/vue-table'
88import { FlexRender } from ' @tanstack/vue-table'
99import { computed } from ' vue'
10+ import { Icon } from ' #components'
1011
1112const props = withDefaults (
1213 defineProps <{
@@ -51,6 +52,26 @@ const getColumnStyles = (column: Column<TData, unknown>) => {
5152
5253 return Object .keys (styles ).length > 0 ? styles : undefined
5354}
55+
56+ const canSort = (column : Column <TData , unknown >) => {
57+ const def = column .columnDef as any
58+ // 如果 enableSorting 明确设置为 false,则不显示排序
59+ if (def .enableSorting === false ) {
60+ return false
61+ }
62+
63+ // 直接检查列定义对象中是否真的存在 accessorKey 或 accessorFn
64+ // 使用 Object.prototype.hasOwnProperty.call 来确保属性直接存在于对象上
65+ const hasAccessorKey =
66+ Object .prototype .hasOwnProperty .call (def , ' accessorKey' ) &&
67+ typeof def .accessorKey === ' string' &&
68+ def .accessorKey .length > 0
69+
70+ const hasAccessorFn = Object .prototype .hasOwnProperty .call (def , ' accessorFn' ) && typeof def .accessorFn === ' function'
71+
72+ // 只有明确配置了 accessorKey 或 accessorFn 时才显示排序
73+ return hasAccessorKey || hasAccessorFn
74+ }
5475 </script >
5576
5677<template >
@@ -73,11 +94,19 @@ const getColumnStyles = (column: Column<TData, unknown>) => {
7394 :class =" bodyHeight ? undefined : 'py-2'"
7495 :style =" getColumnStyles(header.column)"
7596 >
76- <FlexRender
77- v-if =" !header.isPlaceholder"
78- :render =" header.column.columnDef.header"
79- :props =" header.getContext()"
80- />
97+ <template v-if =" ! header .isPlaceholder " >
98+ <div
99+ v-if =" canSort(header.column)"
100+ class =" flex items-center gap-2 cursor-pointer select-none hover:text-foreground"
101+ @click =" header.column.getToggleSortingHandler()?.($event)"
102+ >
103+ <FlexRender :render =" header.column.columnDef.header" :props =" header.getContext()" />
104+ <Icon v-if =" header.column.getIsSorted() === 'asc'" name =" ri:arrow-up-s-line" class =" size-4" />
105+ <Icon v-else-if =" header.column.getIsSorted() === 'desc'" name =" ri:arrow-down-s-line" class =" size-4" />
106+ <Icon v-else name =" ri:arrow-up-down-line" class =" size-4 text-muted-foreground opacity-50" />
107+ </div >
108+ <FlexRender v-else :render =" header.column.columnDef.header" :props =" header.getContext()" />
109+ </template >
81110 </TableHead >
82111 </TableRow >
83112 </TableHeader >
0 commit comments