Skip to content

Commit a78800a

Browse files
committed
feat: add lazyload prop. change $el to $refs
1 parent ba03b8e commit a78800a

File tree

2 files changed

+108
-45
lines changed

2 files changed

+108
-45
lines changed

src/components/VueImageKit.vue

Lines changed: 86 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,39 @@
11
<template>
2-
<div class="vue-image-kit">
3-
<div v-if="dataUrl" class="vue-image-kit__placeholder" :style="{ backgroundColor }">
4-
<img :src="placeholder || dataUrl" alt="Placeholder" :style="{ width: `${width}px`, height: `${height}px` }"/>
5-
</div>
6-
<img class="vue-image-kit__img" :sizes="getSizes" :alt="alt" :style="{ width: `${width}px`, height: `${height}px` }"/>
2+
<div
3+
:class="{ 'vue-image-kit--loaded': !lazyLoad }"
4+
class="vue-image-kit"
5+
ref="main"
6+
>
7+
<template v-if="lazyLoad">
8+
<div
9+
v-if="getDataUrl"
10+
:key="getRandomId"
11+
:style="{ backgroundColor }"
12+
class="vue-image-kit__placeholder"
13+
>
14+
<img
15+
:src="placeholder || getDataUrl"
16+
:style="{ width: `${width}px`, height: `${height}px` }"
17+
alt="Placeholder"
18+
ref="placeholder"
19+
/>
20+
</div>
21+
<img
22+
:sizes="getSizes"
23+
:style="{ width: `${width}px`, height: `${height}px` }"
24+
:alt="alt"
25+
class="vue-image-kit__img"
26+
ref="lazyLoad"
27+
/>
28+
</template>
29+
<img
30+
v-else
31+
:sizes="getSizes"
32+
:style="{ width: `${width}px`, height: `${height}px` }"
33+
:alt="alt"
34+
ref="normalLoad"
35+
class="vue-image-kit__img"
36+
/>
737
</div>
838
</template>
939

@@ -54,6 +84,10 @@ export default {
5484
customTransform: {
5585
type: String,
5686
default: ''
87+
},
88+
lazyLoad: {
89+
type: Boolean,
90+
default: true
5791
}
5892
},
5993
data: () => ({
@@ -63,7 +97,10 @@ export default {
6397
timeOut: null
6498
}),
6599
computed: {
66-
dataUrl () {
100+
getRandomId () {
101+
return Math.random().toString(36).substr(2, 9)
102+
},
103+
getDataUrl () {
67104
const { width, height, showCanvas } = this
68105
69106
if (!width || !height || !showCanvas) return ''
@@ -79,7 +116,9 @@ export default {
79116
const { srcset, imageKitPrefix, hash, customTransform, src } = this
80117
81118
return srcset
82-
.map(size => `${imageKitPrefix}/${hash}/tr:w-${size}${customTransform ? ',' + customTransform : ''}/${src} ${size}w`)
119+
.map(size => `${imageKitPrefix}/${hash}/tr:w-${size}${customTransform
120+
? ',' + customTransform
121+
: ''}/${src} ${size}w`)
83122
.join(', ')
84123
},
85124
getSizes () {
@@ -98,49 +137,65 @@ export default {
98137
}
99138
},
100139
mounted () {
101-
this.showCanvas = true
102-
this.observer = new IntersectionObserver(([entry]) => {
103-
this.triggerIntersection(entry)
104-
})
105-
this.observer.observe(this.$el)
106-
this.$once('hook:beforeDestroy', () => {
107-
this.observer.disconnect()
108-
109-
if (this.timeOut) {
110-
clearTimeout(this.timeOut)
111-
}
112-
})
140+
if (this.lazyLoad) {
141+
this.initLazyLoad()
142+
return
143+
}
144+
145+
this.initNormalLoad()
113146
},
114147
methods: {
148+
initNormalLoad () {
149+
const img = this.$refs.normalLoad
150+
this.setImgAttributes(img)
151+
},
152+
initLazyLoad () {
153+
this.showCanvas = true
154+
this.observer = new IntersectionObserver(([entry]) => {
155+
this.triggerIntersection(entry)
156+
})
157+
this.observer.observe(this.$refs.main)
158+
this.$once('hook:beforeDestroy', () => {
159+
this.observer.disconnect()
160+
161+
if (this.timeOut) {
162+
clearTimeout(this.timeOut)
163+
}
164+
})
165+
},
115166
onloadImage (imgEl) {
116167
delete imgEl.onload
117-
const { $el } = this
118-
const placeholder = $el.querySelector('.vue-image-kit__placeholder')
168+
const { main, placeholder } = this.$refs
119169
120-
$el.classList.add('vue-image-kit--loaded')
170+
if (main) {
171+
main.classList.add('vue-image-kit--loaded')
172+
}
121173
122174
if (placeholder) {
123175
this.timeOut = setTimeout(() => {
124176
placeholder.remove()
125177
}, 300)
126178
}
127179
},
180+
setImgAttributes (img) {
181+
const { srcset, getSrcset, imageKitPrefix, hash, src } = this
182+
this.showCanvas = false
183+
184+
if (srcset) {
185+
img.srcset = getSrcset
186+
}
187+
188+
img.src = `${imageKitPrefix}/${hash}/${src}`
189+
},
128190
triggerIntersection (entry = {}) {
129-
const { $el, srcset, getSrcset, imageKitPrefix, hash, src } = this
130-
const img = $el.querySelector('.vue-image-kit__img')
191+
const img = this.$refs.lazyLoad
131192
132193
img.onload = function () {
133194
this.onloadImage(img)
134195
}.bind(this)
135196
136197
if (entry.isIntersecting) {
137-
this.showCanvas = false
138-
139-
if (srcset) {
140-
img.srcset = getSrcset
141-
}
142-
143-
img.src = `${imageKitPrefix}/${hash}/${src}`
198+
this.setImgAttributes(img)
144199
this.observer.disconnect()
145200
}
146201
}

stories/index.stories.js

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable import/no-extraneous-dependencies */
22
import { storiesOf } from '@storybook/vue'
3-
import { withKnobs, array, text, number } from '@storybook/addon-knobs'
3+
import { withKnobs, array, text, number, boolean } from '@storybook/addon-knobs'
44
import VueImageKit from '../src/components/VueImageKit'
55

66
const timelineStory = storiesOf('VueImageKit', module)
@@ -67,20 +67,28 @@ timelineStory.add('Default', () => {
6767
alt: {
6868
type: String,
6969
default: text('Alt', '')
70+
},
71+
lazyLoad: {
72+
type: Boolean,
73+
default: boolean('Lazy Load', true)
7074
}
7175
},
72-
template: `<div><div style="height:4500px;width:100vw;background:gray">&nbsp;</div><vue-image-kit
73-
:hash="hash"
74-
:src="src"
75-
:placeholder="placeholder"
76-
:background-color="backgroundColor"
77-
:srcset="srcset"
78-
:sizes="sizes"
79-
:width="width"
80-
:height="height"
81-
:alt="alt"
82-
:default-size="defaultSize"
83-
:custom-transform="customTransform"
84-
/></div>`
76+
template: `<div>
77+
<div style="height:2500px;width:100vw;background:gray">&nbsp;</div>
78+
<vue-image-kit
79+
:hash="hash"
80+
:src="src"
81+
:placeholder="placeholder"
82+
:background-color="backgroundColor"
83+
:srcset="srcset"
84+
:sizes="sizes"
85+
:width="width"
86+
:height="height"
87+
:alt="alt"
88+
:lazy-load="lazyLoad"
89+
:default-size="defaultSize"
90+
:custom-transform="customTransform"
91+
/>
92+
</div>`
8593
}
8694
})

0 commit comments

Comments
 (0)