1- import React from 'react' ;
1+ import React , { useEffect , useRef } from 'react' ;
22
33import CopyUtils from '../utils/copy' ;
44import { HotTable } from '@handsontable/react' ;
@@ -7,7 +7,7 @@ import 'handsontable/dist/handsontable.full.css';
77import 'handsontable/languages/zh-CN.js' ;
88import './style.scss' ;
99
10- export interface SpreadSheetProps {
10+ export interface ISpreadSheetProps {
1111 data : Array < Array < string > > ;
1212 columns : any ;
1313 className ?: string ;
@@ -16,77 +16,71 @@ export interface SpreadSheetProps {
1616 } ;
1717}
1818
19- class SpreadSheet extends React . PureComponent < SpreadSheetProps , any > {
20- tableRef : any = React . createRef ( ) ;
21- copyUtils = new CopyUtils ( ) ;
22- _renderTimer : any ;
19+ const SpreadSheet : React . FC < ISpreadSheetProps > = ( { data , columns = [ ] , className , options } ) = > {
20+ const tableRef = useRef < any > ( null ) ;
21+ const copyUtils = new CopyUtils ( ) ;
22+ const _timer = useRef < number > ( ) ;
2323
24- componentDidUpdate ( prevProps : any , _prevState : any ) {
25- if ( prevProps != this . props ) {
26- if ( this . tableRef ) {
27- this . removeRenderClock ( ) ;
28- this . _renderTimer = setTimeout ( ( ) => {
29- console . log ( 'render sheet' ) ;
30- this . tableRef . current . hotInstance . render ( ) ;
31- } , 100 ) ;
32- }
24+ useEffect ( ( ) => {
25+ if ( tableRef . current ) {
26+ removeRenderClock ( ) ;
27+ _timer . current = window . setTimeout ( ( ) => {
28+ tableRef . current . hotInstance . render ( ) ;
29+ } , 100 ) ;
3330 }
34- }
35- removeRenderClock ( ) {
36- if ( this . _renderTimer ) {
37- clearTimeout ( this . _renderTimer ) ;
38- }
39- }
40- componentWillUnmount ( ) {
41- this . removeRenderClock ( ) ;
42- }
43- getData ( ) {
44- const { data, columns = [ ] } = this . props ;
31+ return ( ) => {
32+ removeRenderClock ( ) ;
33+ } ;
34+ } , [ data , columns ] ) ;
35+
36+ const removeRenderClock = ( ) => {
37+ clearTimeout ( _timer . current ) ;
38+ } ;
39+
40+ const getData = ( ) => {
4541 let showData = data ;
46- if ( ! showData || ! showData . length ) {
42+ if ( ! showData ? .length ) {
4743 const emptyArr = new Array ( columns . length ) . fill ( '' , 0 , columns . length ) ;
4844 emptyArr [ 0 ] = '暂无数据' ;
4945 showData = [ emptyArr ] ;
5046 }
5147 return showData ;
52- }
53- getMergeCells ( ) {
54- const { data , columns = [ ] } = this . props ;
55- if ( ! data || ! data . length ) {
48+ } ;
49+
50+ const getMergeCells = ( ) => {
51+ if ( ! data ? .length ) {
5652 return [ { row : 0 , col : 0 , rowspan : 1 , colspan : columns . length } ] ;
5753 }
58- return null ;
59- }
60- getCell ( ) {
61- const { data } = this . props ;
54+ } ;
55+
56+ const getCell = ( ) => {
6257 if ( ! data || ! data . length ) {
6358 return [ { row : 0 , col : 0 , className : 'htCenter htMiddle' } ] ;
6459 }
65- return null ;
66- }
67- beforeCopy ( arr : any , _arr2 ?: any ) {
60+ } ;
61+
62+ const beforeCopy = ( arr : any [ ] ) => {
6863 /**
6964 * 去除格式化
7065 */
7166 const value = arr
72- . map ( ( row : any ) => {
67+ . map ( ( row : any [ ] ) => {
7368 return row . join ( '\t' ) ;
7469 } )
7570 . join ( '\n' ) ;
76- this . copyUtils . copy ( value ) ;
71+ copyUtils . copy ( value ) ;
7772 return false ;
78- }
79- getContextMenu ( ) {
80- const that = this ;
81- const { columns = [ ] , options } = this . props ;
82- const items : any = {
73+ } ;
74+
75+ const getContextMenu = ( ) => {
76+ const items : Record < string , { name : string ; callback : Function } > = {
8377 copy : {
8478 name : '复制' ,
8579 callback : function ( this : any , _key : any ) {
8680 const indexArr = this . getSelected ( ) ;
8781 // eslint-disable-next-line prefer-spread
8882 const copyDataArr = this . getData . apply ( this , indexArr [ 0 ] ) ;
89- that . beforeCopy ( copyDataArr ) ;
83+ beforeCopy ( copyDataArr ) ;
9084 } ,
9185 } ,
9286 } ;
@@ -106,7 +100,7 @@ class SpreadSheet extends React.PureComponent<SpreadSheetProps, any> {
106100 if ( columnArr ) {
107101 copyDataArr = [ columnArr , ...copyDataArr ] ;
108102 }
109- that . beforeCopy ( copyDataArr ) ;
103+ beforeCopy ( copyDataArr ) ;
110104 } ,
111105 } ;
112106 // 目前版本不支持 copy_with_column_headers 暂时用 cut 代替,以达到与copy类似的表现
@@ -115,41 +109,33 @@ class SpreadSheet extends React.PureComponent<SpreadSheetProps, any> {
115109 return {
116110 items,
117111 } as any ;
118- }
112+ } ;
113+
114+ return (
115+ < HotTable
116+ ref = { tableRef }
117+ className = { classNames ( 'dtc-handsontable-no-border' , className ) }
118+ language = "zh-CN"
119+ // 空数组情况,不显示colHeaders,否则colHeaders默认会按照 A、B...显示
120+ // 具体可见 https://handsontable.com/docs/7.1.1/Options.html#colHeaders
121+ colHeaders = { columns ?. length > 0 ? columns : false }
122+ data = { getData ( ) }
123+ mergeCells = { getMergeCells ( ) }
124+ cell = { getCell ( ) }
125+ readOnly
126+ rowHeaders // 数字行号
127+ fillHandle = { false } // 拖动复制单元格
128+ manualRowResize // 拉伸功能
129+ manualColumnResize // 拉伸功能
130+ autoColumnSize
131+ colWidths = { 200 }
132+ beforeCopy = { beforeCopy }
133+ beforeCut = { ( ) => false }
134+ columnHeaderHeight = { 25 }
135+ contextMenu = { getContextMenu ( ) }
136+ stretchH = "all" // 填充空白区域
137+ />
138+ ) ;
139+ } ;
119140
120- render ( ) {
121- const { columns = [ ] , className = '' } = this . props ;
122- const showData = this . getData ( ) ;
123- // 空数组情况,不显示colHeaders,否则colHeaders默认会按照 A、B...显示
124- // 具体可见 https://handsontable.com/docs/7.1.1/Options.html#colHeaders
125- let isShowColHeaders = false ;
126- if ( columns && columns . length > 0 ) {
127- isShowColHeaders = true ;
128- }
129- return (
130- // @ts -ignore
131- < HotTable
132- ref = { this . tableRef }
133- className = { classNames ( 'dtc-handsontable-no-border' , className ) }
134- style = { { width : '100%' } }
135- language = "zh-CN"
136- colHeaders = { isShowColHeaders ? columns : false }
137- data = { showData }
138- mergeCells = { this . getMergeCells ( ) }
139- cell = { this . getCell ( ) }
140- readOnly
141- rowHeaders // 数字行号
142- fillHandle = { false } // 拖动复制单元格
143- manualRowResize // 拉伸功能
144- manualColumnResize // 拉伸功能
145- colWidths = { 200 }
146- beforeCopy = { this . beforeCopy . bind ( this ) }
147- beforeCut = { ( ) => false }
148- columnHeaderHeight = { 25 }
149- contextMenu = { this . getContextMenu ( ) }
150- stretchH = "all" // 填充空白区域
151- />
152- ) ;
153- }
154- }
155141export default SpreadSheet ;
0 commit comments