@@ -32,6 +32,8 @@ function EditableTable<T extends object = Record<string, unknown>>(
3232 const originalDataRef = useRef < Map < string , T > > ( new Map ( ) ) ;
3333 const dataRef = useRef < T [ ] > ( [ ] ) ;
3434 dataRef . current = data ;
35+ const mountedRef = useRef ( true ) ;
36+ useEffect ( ( ) => ( ) => { mountedRef . current = false ; } , [ ] ) ;
3537
3638 const getColKey = useCallback ( ( col : EditableColumn < T > , idx : number ) => {
3739 if ( col . key ) return col . key ;
@@ -59,15 +61,16 @@ function EditableTable<T extends object = Record<string, unknown>>(
5961 // ===== 校验 =====
6062 const validateAll = useCallback ( ( ) : ValidateAllResult => {
6163 const allErrors : Record < string , string > = { } ;
62- data . forEach ( ( row , rowIndex ) => {
64+ data . forEach ( ( row ) => {
65+ const rowId = String ( row [ rowKey ] ) ;
6366 const rowErrors = validateRow ( row , columns ) ;
6467 for ( const [ dataIndex , msg ] of Object . entries ( rowErrors ) ) {
65- allErrors [ `${ rowIndex } -${ dataIndex } ` ] = msg ;
68+ allErrors [ `${ rowId } -${ dataIndex } ` ] = msg ;
6669 }
6770 } ) ;
6871 setErrors ( allErrors ) ;
6972 return { isValid : Object . keys ( allErrors ) . length === 0 , errors : allErrors } ;
70- } , [ data , columns ] ) ;
73+ } , [ data , columns , rowKey ] ) ;
7174
7275 // ===== 通过 ref 暴露操作方法 =====
7376 useImperativeHandle (
@@ -84,18 +87,6 @@ function EditableTable<T extends object = Record<string, unknown>>(
8487 removeRow : ( rowIndex ) => {
8588 setData ( ( prev ) => {
8689 const next = prev . filter ( ( _ , i ) => i !== rowIndex ) ;
87- // 重新映射错误索引
88- setErrors ( ( errs ) => {
89- const nextErrs : Record < string , string > = { } ;
90- for ( const [ k , v ] of Object . entries ( errs ) ) {
91- const dashIdx = k . indexOf ( '-' ) ;
92- const ri = Number ( k . slice ( 0 , dashIdx ) ) ;
93- const rest = k . slice ( dashIdx ) ;
94- if ( ri < rowIndex ) nextErrs [ k ] = v ;
95- else if ( ri > rowIndex ) nextErrs [ `${ ri - 1 } ${ rest } ` ] = v ;
96- }
97- return nextErrs ;
98- } ) ;
9990 onChange ?.( next ) ;
10091 return next ;
10192 } ) ;
@@ -108,18 +99,6 @@ function EditableTable<T extends object = Record<string, unknown>>(
10899 onChange ?.( next ) ;
109100 return next ;
110101 } ) ;
111- setErrors ( ( prev ) => {
112- const next : Record < string , string > = { } ;
113- for ( const [ k , v ] of Object . entries ( prev ) ) {
114- const dashIdx = k . indexOf ( '-' ) ;
115- const ri = Number ( k . slice ( 0 , dashIdx ) ) ;
116- const rest = k . slice ( dashIdx ) ;
117- if ( ri === rowIndex - 1 ) next [ `${ rowIndex } ${ rest } ` ] = v ;
118- else if ( ri === rowIndex ) next [ `${ rowIndex - 1 } ${ rest } ` ] = v ;
119- else next [ k ] = v ;
120- }
121- return next ;
122- } ) ;
123102 } ,
124103 moveDown : ( rowIndex ) => {
125104 if ( rowIndex >= dataRef . current . length - 1 ) return ;
@@ -129,18 +108,6 @@ function EditableTable<T extends object = Record<string, unknown>>(
129108 onChange ?.( next ) ;
130109 return next ;
131110 } ) ;
132- setErrors ( ( prev ) => {
133- const next : Record < string , string > = { } ;
134- for ( const [ k , v ] of Object . entries ( prev ) ) {
135- const dashIdx = k . indexOf ( '-' ) ;
136- const ri = Number ( k . slice ( 0 , dashIdx ) ) ;
137- const rest = k . slice ( dashIdx ) ;
138- if ( ri === rowIndex ) next [ `${ rowIndex + 1 } ${ rest } ` ] = v ;
139- else if ( ri === rowIndex + 1 ) next [ `${ rowIndex } ${ rest } ` ] = v ;
140- else next [ k ] = v ;
141- }
142- return next ;
143- } ) ;
144111 } ,
145112 getData : ( ) => dataRef . current ,
146113 validateAll,
@@ -158,17 +125,6 @@ function EditableTable<T extends object = Record<string, unknown>>(
158125 setData ( ( prev ) => {
159126 const next = [ ...prev ] ;
160127 next . splice ( rowIndex , 0 , newRow ) ;
161- setErrors ( ( errs ) => {
162- const nextErrs : Record < string , string > = { } ;
163- for ( const [ k , v ] of Object . entries ( errs ) ) {
164- const dashIdx = k . indexOf ( '-' ) ;
165- const ri = Number ( k . slice ( 0 , dashIdx ) ) ;
166- const rest = k . slice ( dashIdx ) ;
167- if ( ri < rowIndex ) nextErrs [ k ] = v ;
168- else nextErrs [ `${ ri + 1 } ${ rest } ` ] = v ;
169- }
170- return nextErrs ;
171- } ) ;
172128 onChange ?.( next ) ;
173129 return next ;
174130 } ) ;
@@ -201,6 +157,7 @@ function EditableTable<T extends object = Record<string, unknown>>(
201157 const rowId = String ( currentRow [ rowKey ] ) ;
202158 linkedResult . then ( ( updates ) => {
203159 if ( ! updates ) return ;
160+ if ( ! mountedRef . current ) return ;
204161 setData ( ( prev ) => {
205162 const idx = prev . findIndex ( ( r ) => String ( r [ rowKey ] ) === rowId ) ;
206163 if ( idx === - 1 ) return prev ;
@@ -209,6 +166,8 @@ function EditableTable<T extends object = Record<string, unknown>>(
209166 onChange ?.( next ) ;
210167 return next ;
211168 } ) ;
169+ } ) . catch ( ( err ) => {
170+ console . error ( '[EditableTable] onFieldChange error' , err ) ;
212171 } ) ;
213172 } else if ( linkedResult ) {
214173 setData ( ( prev ) => {
@@ -225,7 +184,8 @@ function EditableTable<T extends object = Record<string, unknown>>(
225184 const row = dataRef . current [ rowIndex ] ;
226185 const updatedRow = { ...row , [ dataIndex ] : value } ;
227186 const err = validateValue ( value , updatedRow , col . rules ) ;
228- const key = `${ rowIndex } -${ dataIndex } ` ;
187+ const rowId = String ( row [ rowKey ] ) ;
188+ const key = `${ rowId } -${ dataIndex } ` ;
229189 setErrors ( ( prev ) => {
230190 const next = { ...prev } ;
231191 if ( err ) next [ key ] = err ;
@@ -249,7 +209,7 @@ function EditableTable<T extends object = Record<string, unknown>>(
249209 // 已在编辑中则不覆盖快照,保留最初的原始数据
250210 if ( editingRows . has ( id ) ) return ;
251211 const row = data . find ( ( r ) => String ( r [ rowKey ] ) === id ) ;
252- if ( row ) originalDataRef . current . set ( id , { ...row } ) ;
212+ if ( row ) originalDataRef . current . set ( id , typeof structuredClone === 'function' ? structuredClone ( row ) : { ...row } ) ;
253213 setEditingRows ( ( prev ) => new Set ( prev ) . add ( id ) ) ;
254214 } ,
255215 [ data , rowKey , editingRows ] ,
@@ -262,12 +222,12 @@ function EditableTable<T extends object = Record<string, unknown>>(
262222 const rowErrors = validateRow ( data [ rowIndex ] , columns ) ;
263223 const rowKeyErrors : Record < string , string > = { } ;
264224 for ( const [ dataIndex , msg ] of Object . entries ( rowErrors ) ) {
265- rowKeyErrors [ `${ rowIndex } -${ dataIndex } ` ] = msg ;
225+ rowKeyErrors [ `${ id } -${ dataIndex } ` ] = msg ;
266226 }
267227 setErrors ( ( prev ) => {
268228 const next : Record < string , string > = { } ;
269229 for ( const [ k , v ] of Object . entries ( prev ) ) {
270- if ( ! k . startsWith ( `${ rowIndex } -` ) ) next [ k ] = v ;
230+ if ( ! k . startsWith ( `${ id } -` ) ) next [ k ] = v ;
271231 }
272232 Object . assign ( next , rowKeyErrors ) ;
273233 return next ;
@@ -297,15 +257,13 @@ function EditableTable<T extends object = Record<string, unknown>>(
297257 } ) ;
298258 }
299259 originalDataRef . current . delete ( id ) ;
300- if ( rowIndex !== - 1 ) {
301- setErrors ( ( prev ) => {
302- const n : Record < string , string > = { } ;
303- for ( const [ k , v ] of Object . entries ( prev ) ) {
304- if ( ! k . startsWith ( `${ rowIndex } -` ) ) n [ k ] = v ;
305- }
306- return n ;
307- } ) ;
308- }
260+ setErrors ( ( prev ) => {
261+ const n : Record < string , string > = { } ;
262+ for ( const [ k , v ] of Object . entries ( prev ) ) {
263+ if ( ! k . startsWith ( `${ id } -` ) ) n [ k ] = v ;
264+ }
265+ return n ;
266+ } ) ;
309267 setEditingRows ( ( prev ) => {
310268 const n = new Set ( prev ) ;
311269 n . delete ( id ) ;
@@ -343,7 +301,7 @@ function EditableTable<T extends object = Record<string, unknown>>(
343301 const cols = columns . map ( ( col ) => {
344302 if ( col . width ) {
345303 const w = typeof col . width === 'number' ? col . width : parseInt ( col . width as string , 10 ) || 150 ;
346- return `minmax(${ w } px, ${ w } fr )` ;
304+ return `minmax(${ w } px, 1fr )` ;
347305 }
348306 return 'minmax(150px, 1fr)' ;
349307 } ) . join ( ' ' ) ;
@@ -359,22 +317,22 @@ function EditableTable<T extends object = Record<string, unknown>>(
359317 return 150 ;
360318 } ) ;
361319
362- // 从左往右累计 left fixed
320+ // 从左往右累计 left fixed(只累加已标记 fixed='left' 的列宽)
363321 let leftAcc = 0 ;
364322 for ( let i = 0 ; i < columns . length ; i ++ ) {
365323 if ( columns [ i ] . fixed === 'left' ) {
366324 offsets [ i ] = { left : leftAcc } ;
325+ leftAcc += widths [ i ] ;
367326 }
368- leftAcc += widths [ i ] ;
369327 }
370328
371- // 从右往左累计 right fixed
329+ // 从右往左累计 right fixed(只累加已标记 fixed='right' 的列宽)
372330 let rightAcc = 0 ;
373331 for ( let i = columns . length - 1 ; i >= 0 ; i -- ) {
374332 if ( columns [ i ] . fixed === 'right' ) {
375333 offsets [ i ] = { right : rightAcc } ;
334+ rightAcc += widths [ i ] ;
376335 }
377- rightAcc += widths [ i ] ;
378336 }
379337
380338 return offsets ;
@@ -492,7 +450,7 @@ function EditableTable<T extends object = Record<string, unknown>>(
492450 ? col . editable !== false
493451 : isEditing && col . editable !== false ;
494452 const errorKey = colDataIndex
495- ? `${ virtualRow . index } -${ colDataIndex } `
453+ ? `${ id } -${ colDataIndex } `
496454 : undefined ;
497455 const offset = fixedOffsets [ colIndex ] ;
498456 const isFixed = col . fixed === 'left' || col . fixed === 'right' ;
@@ -583,6 +541,8 @@ function EditableTable<T extends object = Record<string, unknown>>(
583541 style = { {
584542 display : 'grid' ,
585543 gridTemplateColumns : gridTemplate ,
544+ width : 'fit-content' ,
545+ minWidth : '100%' ,
586546 } }
587547 >
588548 { columns . map ( ( col , colIndex ) => {
@@ -594,7 +554,7 @@ function EditableTable<T extends object = Record<string, unknown>>(
594554 editableMode === 'all'
595555 ? col . editable !== false
596556 : isEditing && col . editable !== false ;
597- const errorKey = colDataIndex ? `${ rowIndex } -${ colDataIndex } ` : undefined ;
557+ const errorKey = colDataIndex ? `${ id } -${ colDataIndex } ` : undefined ;
598558 const offset = fixedOffsets [ colIndex ] ;
599559 const isFixed = col . fixed === 'left' || col . fixed === 'right' ;
600560
0 commit comments