Skip to content

Commit 7eab822

Browse files
committed
feat: fix Attributes
1 parent 0b1e0e5 commit 7eab822

File tree

2 files changed

+224
-26
lines changed

2 files changed

+224
-26
lines changed

src/components/LazyLoadComponent.tsx

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,6 @@ export default defineComponent({
4040
type: Number,
4141
default: 0
4242
},
43-
// placeholder:{
44-
// type: Object,
45-
// default: null
46-
// },
4743
width: {
4844
type: Number,
4945
default: 0
@@ -56,8 +52,29 @@ export default defineComponent({
5652
type: Number,
5753
default: 300
5854
},
55+
style: {
56+
type: Object,
57+
default: () => { }
58+
},
59+
class: {
60+
type: String,
61+
default: ''
62+
},
63+
delayMethod: {
64+
type: String,
65+
default: 'throttle'
66+
},
67+
delayTime: {
68+
type: Number,
69+
default: 300
70+
},
71+
placeholder: {
72+
type: Object,
73+
default: () => { }
74+
}
75+
5976
},
60-
setup(props, { slots }) {
77+
setup(props, { slots, attrs }) {
6178
const state = reactive({
6279
visible: props.visibleByDefault ?? false,
6380
loaded: false,
@@ -95,28 +112,33 @@ export default defineComponent({
95112
return () => {
96113
return isScrollTracked ||
97114
(props.useIntersectionObserver && isIntersectionObserverAvailable()) ?
98-
<PlaceholderWithoutTracking
99-
height={props.height}
100-
onVisible={onVisible}
101-
// placeholder={props.placeholder}
102-
scrollPosition={props.scrollPosition}
103-
threshold={props.threshold}
104-
useIntersectionObserver={props.useIntersectionObserver}
105-
width={props.width}
106-
>
107-
{slots.default?.()}
108-
</PlaceholderWithoutTracking>
115+
<>
116+
<PlaceholderWithoutTracking
117+
height={props.height}
118+
onVisible={onVisible}
119+
// placeholder={props.placeholder}
120+
scrollPosition={props.scrollPosition}
121+
threshold={props.threshold}
122+
useIntersectionObserver={props.useIntersectionObserver}
123+
width={props.width}
124+
>
125+
{slots.default?.()}
126+
</PlaceholderWithoutTracking>
127+
</>
109128
:
110-
<PlaceholderWithTracking
111-
height={props.height}
112-
onVisible={onVisible}
113-
// placeholder={props.placeholder}
114-
scrollPosition={props.scrollPosition}
115-
threshold={props.threshold}
116-
useIntersectionObserver={props.useIntersectionObserver}
117-
width={props.width}
118-
>{slots.default?.()}
119-
</PlaceholderWithTracking>
129+
<>
130+
<PlaceholderWithTracking
131+
height={props.height}
132+
onVisible={onVisible}
133+
// placeholder={props.placeholder}
134+
scrollPosition={props.scrollPosition}
135+
threshold={props.threshold}
136+
useIntersectionObserver={props.useIntersectionObserver}
137+
width={props.width}
138+
>
139+
{slots.default?.()}
140+
</PlaceholderWithTracking>
141+
</>
120142
}
121143
}
122144
})

src/components/LazyLoadImage.tsx

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
import { computed, defineComponent, ref } from 'vue';
2+
import LazyLoadComponent from './LazyLoadComponent.jsx';
3+
4+
export default defineComponent({
5+
name: 'LazyLoadImage',
6+
props: {
7+
afterLoad: {
8+
type: Function,
9+
default: () => { }
10+
},
11+
beforeLoad: {
12+
type: Function,
13+
default: () => { }
14+
},
15+
scrollPosition: {
16+
type: Object,
17+
default: null
18+
},
19+
visibleByDefault: {
20+
type: Boolean,
21+
default: false
22+
},
23+
height: {
24+
type: Number,
25+
default: 0
26+
},
27+
width: {
28+
type: Number,
29+
default: 0
30+
},
31+
useIntersectionObserver: {
32+
type: Boolean,
33+
default: true
34+
},
35+
threshold: {
36+
type: Number,
37+
default: 300
38+
},
39+
placeholderSrc: {
40+
type: String,
41+
default: ''
42+
},
43+
effect: {
44+
type: String,
45+
default: ''
46+
},
47+
loadedClassName: {
48+
type: String,
49+
default: ''
50+
},
51+
wrapperClassName: {
52+
type: String,
53+
default: ''
54+
},
55+
wrapperProps: {
56+
type: Object,
57+
default: () => { }
58+
},
59+
delayTime: {
60+
type: Number,
61+
default: 300
62+
},
63+
delayMethod: {
64+
type: String,
65+
default: 'debounce'
66+
},
67+
placeholder: {
68+
type: Object,
69+
default: null
70+
},
71+
class: {
72+
type: String,
73+
default: ''
74+
},
75+
style: {
76+
type: Object,
77+
default: () => { }
78+
}
79+
},
80+
setup(props, { attrs }) {
81+
const loaded = ref(false);
82+
function onImageLoad() {
83+
if (!loaded.value) {
84+
return null
85+
}
86+
return () => {
87+
props.afterLoad?.()
88+
loaded.value = true
89+
}
90+
}
91+
function getImg() {
92+
const imgProps = computed(() => {
93+
const {
94+
class: className,
95+
afterLoad,
96+
beforeLoad,
97+
delayMethod,
98+
delayTime,
99+
effect,
100+
placeholder,
101+
placeholderSrc,
102+
scrollPosition,
103+
threshold,
104+
useIntersectionObserver,
105+
visibleByDefault,
106+
wrapperClassName,
107+
wrapperProps,
108+
style,
109+
loadedClassName,
110+
...imgProps
111+
} = props;
112+
return imgProps
113+
})
114+
// @ts-ignore
115+
return <img onLoad={onImageLoad()} {...imgProps.value} {...attrs} />
116+
}
117+
function getLazyLoadImage() {
118+
return (
119+
<LazyLoadComponent
120+
beforeLoad={props.beforeLoad}
121+
class={props.class}
122+
delayMethod={props.delayMethod}
123+
delayTime={props.delayTime}
124+
height={props.height}
125+
placeholder={props.placeholder}
126+
scrollPosition={props.scrollPosition}
127+
style={props.style}
128+
threshold={props.threshold}
129+
useIntersectionObserver={props.useIntersectionObserver}
130+
visibleByDefault={props.visibleByDefault}
131+
width={props.width}
132+
>
133+
{getImg()}
134+
</LazyLoadComponent>
135+
)
136+
}
137+
138+
function getWrappedLazyLoadImage(lazyLoadImage: any) {
139+
const wrapperBackground =
140+
loaded.value || !props.placeholderSrc
141+
? {}
142+
: {
143+
backgroundImage: `url(${props.placeholderSrc})`,
144+
backgroundSize: '100% 100%',
145+
};
146+
return (
147+
<span
148+
class={
149+
props.wrapperClassName +
150+
' lazy-load-image-background ' +
151+
props.effect + props.loadedClassName
152+
}
153+
style={{
154+
...wrapperBackground,
155+
color: 'transparent',
156+
display: 'inline-block',
157+
height: props.height,
158+
width: props.width,
159+
}}
160+
{...props.wrapperProps}
161+
>
162+
{lazyLoadImage}
163+
</span>
164+
);
165+
}
166+
167+
return () => {
168+
const lazyLoadImage = getLazyLoadImage();
169+
const needsWrapper = (props.effect || props.placeholderSrc) && !props.visibleByDefault;
170+
if (!needsWrapper && !props.wrapperClassName && !props.wrapperProps) {
171+
return lazyLoadImage;
172+
}
173+
return getWrappedLazyLoadImage(lazyLoadImage);
174+
}
175+
},
176+
});

0 commit comments

Comments
 (0)