Skip to content

Commit 541c588

Browse files
committed
feat(image): add preload
1 parent 694627a commit 541c588

File tree

6 files changed

+115
-1
lines changed

6 files changed

+115
-1
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script setup lang="ts">
2+
const imageProps = {
3+
src: '01.jpg',
4+
width: 900,
5+
height: 600,
6+
alt: 'Image alt text',
7+
provider: 'interventionRequest',
8+
}
9+
</script>
10+
11+
<template>
12+
<NuxtStory>
13+
<VImg v-bind="imageProps" preload />
14+
</NuxtStory>
15+
</template>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script setup lang="ts">
2+
const imageProps = {
3+
src: '01.jpg',
4+
width: 900,
5+
height: 600,
6+
alt: 'Image alt text',
7+
provider: 'interventionRequest',
8+
}
9+
</script>
10+
11+
<template>
12+
<NuxtStory>
13+
<VImg v-bind="imageProps" preload sizes="xs:100vw md:100vw xl:100vw" />
14+
</NuxtStory>
15+
</template>

components/molecules/VImg/VImg.vue

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ export default defineComponent({
8888
})
8989
)
9090
})
91-
9291
const internalSizes = computed(() => {
9392
const result = responsiveImageData.value?.sizes
9493
@@ -97,6 +96,31 @@ export default defineComponent({
9796
return result
9897
})
9998
99+
// @see https://github.com/nuxt/image/blob/main/src/runtime/components/nuxt-img.ts
100+
if (props.preload) {
101+
const isResponsive = responsiveImageData.value && Object.values(responsiveImageData.value).every((v) => v)
102+
103+
useHead({
104+
link: [
105+
{
106+
rel: 'preload',
107+
as: 'image',
108+
nonce: props.nonce,
109+
...(!isResponsive
110+
? { href: src.value }
111+
: {
112+
href: responsiveImageData.value.src,
113+
imagesizes: responsiveImageData.value.sizes,
114+
imagesrcset: responsiveImageData.value.srcset,
115+
}),
116+
...(typeof props.preload !== 'boolean' && props.preload.fetchPriority
117+
? { fetchpriority: props.preload.fetchPriority }
118+
: {}),
119+
},
120+
],
121+
})
122+
}
123+
100124
return () =>
101125
h('img', {
102126
src: src.value,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script setup lang="ts">
2+
const imageProps = {
3+
src: '01.jpg',
4+
width: 900,
5+
height: 600,
6+
alt: 'Image alt text',
7+
provider: 'interventionRequest',
8+
}
9+
</script>
10+
11+
<template>
12+
<NuxtStory>
13+
<VPicture v-bind="imageProps" preload />
14+
</NuxtStory>
15+
</template>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script setup lang="ts">
2+
const imageProps = {
3+
src: '01.jpg',
4+
width: 900,
5+
height: 600,
6+
alt: 'Image alt text',
7+
provider: 'interventionRequest',
8+
}
9+
</script>
10+
11+
<template>
12+
<NuxtStory>
13+
<VPicture v-bind="imageProps" preload>
14+
<VPictureSource :modifiers="{ crop: '400x600' }" media="(max-width: 1024px)" />
15+
</VPicture>
16+
</NuxtStory>
17+
</template>

components/molecules/VPicture/VPictureSource.vue

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import type { MaybeRefOrGetter, PropType } from 'vue'
33
import type { ImageOptions } from '@nuxt/image'
44
import type { VPictureProps } from '~/components/molecules/VPicture/VPicture.vue'
5+
import type { Head } from '@unhead/schema'
56
67
const props = defineProps({
78
media: String,
@@ -14,6 +15,11 @@ const props = defineProps({
1415
width: String,
1516
height: String,
1617
modifiers: Object as PropType<Record<string, any>>,
18+
preload: {
19+
type: [Boolean, Object] as PropType<boolean | { fetchPriority?: 'auto' | 'high' | 'low' }>,
20+
default: undefined,
21+
},
22+
nonce: String,
1723
})
1824
1925
const pictureProps = inject<MaybeRefOrGetter<VPictureProps>>('pictureProps')
@@ -94,6 +100,28 @@ const sources = computed(() => {
94100
}
95101
})
96102
})
103+
104+
// @see https://github.com/nuxt/image/blob/main/src/runtime/components/nuxt-picture.ts
105+
const picturePropsValue = toValue<VPictureProps>(pictureProps)
106+
const preload = props.preload || (typeof props.preload === 'undefined' && picturePropsValue.preload)
107+
108+
if (preload) {
109+
const link: NonNullable<Head['link']>[number] = {
110+
rel: 'preload',
111+
as: 'image',
112+
imagesrcset: sources.value[0].srcset,
113+
nonce: props.nonce,
114+
...(typeof props.preload !== 'boolean' && preload.fetchPriority
115+
? { fetchpriority: preload.fetchPriority }
116+
: {}),
117+
}
118+
119+
if (sources.value?.[0]?.sizes) {
120+
link.imagesizes = sources.value[0].sizes
121+
}
122+
123+
useHead({ link: [link] })
124+
}
97125
</script>
98126

99127
<template>

0 commit comments

Comments
 (0)