Skip to content

Commit 673351a

Browse files
committed
refactor: use tsx replace render function
1 parent cdcfb3d commit 673351a

File tree

3 files changed

+185
-168
lines changed

3 files changed

+185
-168
lines changed

src/item.tsx

+73-72
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,100 @@
1-
import { defineComponent, h } from 'vue';
1+
import {
2+
computed,
3+
defineComponent,
4+
onMounted,
5+
onUnmounted,
6+
onUpdated,
7+
ref,
8+
Ref,
9+
} from 'vue';
10+
// TODO: remove this
211
import emitter from 'tiny-emitter/instance';
312
import { ItemProps, SlotProps } from './props';
413

5-
const Wrapper = {
6-
created() {
7-
this.shapeKey = this.horizontal ? 'offsetWidth' : 'offsetHeight';
8-
},
14+
const useResizeChange = (props: any, rootRef: Ref<HTMLElement | null>) => {
15+
let resizeObserver: ResizeObserver | null = null;
16+
const shapeKey = computed(() =>
17+
props.horizontal ? 'offsetWidth' : 'offsetHeight',
18+
);
19+
20+
const getCurrentSize = () => {
21+
return rootRef.value ? rootRef.value[shapeKey.value] : 0;
22+
};
923

10-
mounted() {
24+
// tell parent current size identify by unqiue key
25+
const dispatchSizeChange = () => {
26+
const { event, uniqueKey, hasInitial } = props;
27+
console.log(getCurrentSize());
28+
emitter.emit(event, uniqueKey, getCurrentSize(), hasInitial);
29+
};
30+
31+
onMounted(() => {
1132
if (typeof ResizeObserver !== 'undefined') {
12-
this.resizeObserver = new ResizeObserver(() => {
13-
this.dispatchSizeChange();
33+
resizeObserver = new ResizeObserver(() => {
34+
dispatchSizeChange();
1435
});
15-
this.resizeObserver.observe(this.$el);
36+
rootRef.value && resizeObserver.observe(rootRef.value);
1637
}
17-
},
38+
});
1839

19-
// since componet will be reused, so disptach when updated
20-
updated() {
21-
this.dispatchSizeChange();
22-
},
40+
onUpdated(() => {
41+
dispatchSizeChange();
42+
});
2343

24-
beforeDestroy() {
25-
if (this.resizeObserver) {
26-
this.resizeObserver.disconnect();
27-
this.resizeObserver = null;
44+
onUnmounted(() => {
45+
if (resizeObserver) {
46+
resizeObserver.disconnect();
47+
resizeObserver = null;
2848
}
29-
},
30-
31-
methods: {
32-
getCurrentSize() {
33-
return this.$el ? this.$el[this.shapeKey] : 0;
34-
},
35-
36-
// tell parent current size identify by unqiue key
37-
dispatchSizeChange() {
38-
emitter.emit(
39-
this.event,
40-
this.uniqueKey,
41-
this.getCurrentSize(),
42-
this.hasInitial,
43-
);
44-
// this.$parent.$emit(this.event, this.uniqueKey, this.getCurrentSize(), this.hasInitial)
45-
},
46-
},
49+
});
4750
};
4851

4952
export const Item = defineComponent({
5053
name: 'VirtualListItem',
51-
mixins: [Wrapper],
5254
props: ItemProps,
53-
render() {
54-
const {
55-
tag,
56-
component,
57-
extraProps = {},
58-
index,
59-
source,
60-
scopedSlots = {},
61-
uniqueKey,
62-
} = this;
63-
const props = {
64-
...extraProps,
65-
source,
66-
index,
67-
};
55+
setup(props) {
56+
const rootRef = ref<HTMLElement | null>(null);
57+
useResizeChange(props, rootRef);
58+
59+
return () => {
60+
const {
61+
tag: Tag,
62+
component: Comp,
63+
extraProps = {},
64+
index,
65+
source,
66+
scopedSlots = {},
67+
uniqueKey,
68+
} = props;
69+
const mergedProps = {
70+
...extraProps,
71+
source,
72+
index,
73+
};
6874

69-
return h(
70-
tag,
71-
{
72-
key: uniqueKey,
73-
},
74-
[
75-
h(component, {
76-
...props,
77-
scopedSlots: scopedSlots,
78-
}),
79-
],
80-
);
75+
return (
76+
<Tag key={uniqueKey} ref={rootRef}>
77+
<Comp {...mergedProps} scopedSlots={scopedSlots} />
78+
</Tag>
79+
);
80+
};
8181
},
8282
});
8383

8484
export const Slot = defineComponent({
85-
mixins: [Wrapper],
85+
name: 'VirtualListSlot',
8686
props: SlotProps,
8787
setup(props, { slots }) {
88+
const rootRef = ref<HTMLElement | null>(null);
89+
useResizeChange(props, rootRef);
90+
8891
return () => {
89-
const { tag, uniqueKey } = props;
92+
const { tag: Tag, uniqueKey } = props;
9093

91-
return h(
92-
tag,
93-
{
94-
key: uniqueKey,
95-
},
96-
slots.default(),
94+
return (
95+
<Tag ref={rootRef} key={uniqueKey}>
96+
{slots.default?.()}
97+
</Tag>
9798
);
9899
};
99100
},

src/props.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
* props declaration for default, item and slot component
33
*/
44

5+
import { PropType } from 'vue';
6+
57
export const VirtualProps = {
68
dataKey: {
79
type: [String, Function],
@@ -30,7 +32,7 @@ export const VirtualProps = {
3032
},
3133

3234
direction: {
33-
type: String,
35+
type: String as PropType<'vertical' | 'horizontal'>,
3436
default: 'vertical', // the other value is horizontal
3537
},
3638
start: {

0 commit comments

Comments
 (0)