Loading dynamic images in a Vue Component

When I first started using Vue, one thing I got continually wrong was how to load an image into a Vue component dynamically. At first, I found that using an absolute URL worked, but that was only useful if I was storing the images on a CDN or other external site. If I included the images in my project, as either lightweight icons or static images, then using an absolute URL, with hostname and all, didn’t really work. What about when I wanted to test some new images locally or on a dev server? Linking directly to the images in production just wasn’t going to cut it.
When researching this, the Vue CLI documentation for static assets was, frankly, a little less than helpful. They didn’t give a good example for what I was trying to do.
What I was building was a little form control to take credit card numbers. It consisted of a single file Vue component and looked something like this:
What I wanted to happen was, as the user is typing in their credit card number, I will look at it and swap out the img
tag’s source to show the credit card type that they were entering. I had a Visa image, a Mastercard image and a Discover image as well as the image of a generic credit card if it didn’t match any of those. Since all Visas start with 4
, all Mastercards start with 5
, and all Discover cards start with 6
, this would be a pretty easy check to do.
The logic ended up being the easy part. The hard part was loading the images. I had the images in the Vue CLI provided assets
folder, but how do I load them in?
Looking at the documentation, there are a lot of “in templates, do this” and “only in templates!” kinds of things. But I wasn’t in a template. I was in the code part of my component.
After much research, I found the answer was to require()
the images from the asset folder. Intuitive! 😒
So, when I need to use an image that is in the assets
folder, I can require()
the relative path to that image in my computed method:
One nice plus to doing it this way is, if the image is small enough, require()
will return a dataurl instead of a URL path, which will save an extra call to the server and make the component a little more self contained.
So if you need to load images from inside a Vue CLI project’s assets folder from outside the template of your component, now you know how.