I have a Vue App with a Projects page, where I want to have many Project cards that will each have an attached picture.
This is what my Projects.vue route/component looks like currently. I omitted some irrelevant divs and classes for the sake of brevity.
<template>
<div>
<ProjectCard
v-for="project in ProjectList"
:key="project.title"
:title="project.title"
:description="project.description"
:image="require(`../assets/images/projects/${project.name}.jpg`)"
/>
</div>
</template>
<script>
import ProjectCard from "@/components/ProjectCard";
import ProjectList from "@/assets/images/projects/imageList.json";
export default {
name: "Projects",
components: {
ProjectCard
},
data() {
return {
ProjectList
};
}
};
</script>
As you can see, it simply loops through a JSON list and passes some props down to the ProjectCard component.
This is the ProjectCard component
<template>
<div>
<img :src="image" />
<h1>{{ title }}</h1>
<h3>{{ description }}</h3>
</div>
</template>
<script>
export default {
name: "ProjectCard",
props: {
image: String,
title: String,
description: String
}
};
</script>
This works fine, the pictures show up as they should, however I want to now replace my img tag with a picture tag that will have fallbacks for older browsers (as I want to use webp) as well as some responsive image rules.
Obviously, though, I can't just use the same require that I'm using just without a file extension, as then Webpack won't be able to recognize which asset it's supposed to be using.
As far as I see it, the only option I can think of is to have different props for the ProjectCard template that reference each different image format, but this seems like it's too manual of a process. Let's say the directory looks something like this:
projects /
a-small.jpg
a-medium.jpg
a-large.jpg
a-small.webp
a-medium.webp
a-large.webp
I'd have to make 5 additional props, just to get one image showing correctly, instead of just having the one prop that I can pass and just do something like this in the HTML
<picture>
<source media="(max-width: 1400px)" :srcset="`${image}-large.webp`" >
<source media="(max-width: 1000px)" :srcset="`${image}-medium.webp`" >
<source media="(max-width: 600px)" :srcset="`${image}-small.webp`" >
<source media="(max-width: 1400px)" :srcset="`${image}-large.jpg`" >
<source media="(max-width: 1000px)" :srcset="`${image}-medium.jpg`" >
<source media="(max-width: 600px)" :srcset="`${image}-small.jpg`" >
</picture>
Is there any way to do what I'd prefer to do in this situation?
EDIT: Solution
Tony offered a good solution, however I went a much simpler route and simply put my images in the public/ directory. No need to try wrestle with webpack imports this way!