1
- import { Ref , provide , shallowReactive , unref , watchEffect } from "vue" ;
1
+ import { computed , Ref , provide , reactive , unref } from "vue" ;
2
2
import { injectKey , VirtualState } from './state' ;
3
3
4
4
export { default as VirtualScroller } from './scroller.vue' ;
@@ -7,34 +7,32 @@ export { default as VirtualBody } from './body.vue';
7
7
type Val < T > = T | Ref < T > ;
8
8
9
9
export function useVirtual ( data : Val < object [ ] > , size : { height : number } ) {
10
- const state : VirtualState = shallowReactive ( {
10
+ const state : VirtualState = reactive ( {
11
11
scroller : < any > null ! , // initialized on mount // FIXME: TS error if declared as Element?
12
12
scrollTop : 0 ,
13
13
rowHeight : 25 ,
14
14
buffer : 4 ,
15
15
topGap : 0 ,
16
16
bottomGap : 0 ,
17
- index : 0 ,
18
- count : 0 ,
19
17
20
- items : function * ( ) {
21
- const all = unref ( data ) ;
22
- const to = state . index + state . count ;
23
- for ( let i = state . index ; i < to ; i ++ )
24
- yield all [ i ] ;
25
- } ,
26
- } ) ;
18
+ items : computed ( ( ) => {
19
+ // Technically, size.height is slighty too high because it's the height of the full table,
20
+ // including thead, rather than just tbody.
21
+ // That's not an issue though, it just means one or two extra rows will be rendered past the bottom.
22
+ const length = unref ( data ) . length ;
23
+ const { buffer, rowHeight, scrollTop } = state ;
24
+ const index = Math . max ( ( scrollTop / rowHeight | 0 ) - buffer , 0 ) ;
25
+ const count = Math . min ( ( size . height / rowHeight | 0 ) + 1 + buffer + buffer , length - index ) ;
26
+ state . topGap = index * rowHeight ;
27
+ state . bottomGap = ( length - count - index ) * rowHeight ;
27
28
28
- watchEffect ( ( ) => {
29
- // Technically, size.height is slighty too high because it's the height of the full table,
30
- // including thead, rather than just tbody.
31
- // That's not an issue though, it just means one or two extra rows will be rendered past the bottom.
32
- const length = unref ( data ) . length ;
33
- const { buffer, rowHeight, scrollTop } = state ;
34
- const index = state . index = Math . max ( ( scrollTop / rowHeight | 0 ) - buffer , 0 ) ;
35
- const count = state . count = Math . min ( ( size . height / rowHeight | 0 ) + 1 + buffer + buffer , length - index ) ;
36
- state . topGap = index * rowHeight ;
37
- state . bottomGap = ( length - count - index ) * rowHeight ;
29
+ return function * ( ) {
30
+ const all = unref ( data ) ;
31
+ const to = index + count ;
32
+ for ( let i = index ; i < to ; i ++ )
33
+ yield all [ i ] ;
34
+ } ;
35
+ } ) ,
38
36
} ) ;
39
37
40
38
provide ( injectKey , state ) ;
0 commit comments