tgoop.com/vuejs_ru_feed/34
Create:
Last Update:
Last Update:
Работа с картинками в шаблоне!src #help
1. Почему такой код не работает? Картинка точно есть по этому, и без переменной работает!
<img :src="`../assets/images/${image}`" />Собранное приложение в проде имеет другие файлы по другим путям. Путь относительно исходников - некорректный. Чтобы это работало, нужно работать с картинками и другими ресурсами, как с модулями, прогоняя их через сборщик. Сборщик переместит файл, поменяет имя, и вернёт новое имя, а может даже вставит inline-ссылкой (data url).
import Cat from '../images/Cat.png'
console.log(Cat) // выведет /img/Cat.45df63.png
<img :src="Cat" />
2. Но у меня раньше работало без импорта! Например, так:
<img src="@/assets/images/cat.png" />
Сборщик с
@vue/sfc-compiler знает, что в src в HTML и url() в CSS указывается путь. Если он относительный (не с /), то он автоматически работает с ним, как с модулем, сам делая импорт. Но это должен быть статический путь именно в таком атрибуте. :src с привязкой у JS вычислению или даже data-src — работать не будут.<img :src="`@/assets/images/cat.png`" data-src="@/assets/images/cat.png" />
<img src="@/assets/images/dog.png" data-src="@/assets/images/dog.png" />
Превращается в
<img src="@/assets/cat.653gtd.png" data-src="@/assets/images/cat.png" />
<img src="/assets/dog.45df63.png" data-src="@/assets/images/dog.png" />
Только чистый
src обработался, как путь до модуля.3. Что же тогда делать, если надо хранить путь в данных?
Можно использовать:
- Явные импорты, если заранее известен набор файлов
-
require в Webpack-
new URL в Vite (без поддержки алиасов и SSR)-
import.glob в Vite, если нужен список всех файлов// Нам нужна картинка питомца из переменной
const myPet = 'dog'
// Webpack + Vite - прямой импорт
import cat from '@/assets/pets/cat.png'
import dog from '@/assets/pets/dog.png'
const pets = { cat, dog }
const myPetImage = pets[myPet]
// Webpack - require
const myPetImage = require(`../assets/pets/${myPet}.png`)
// Vite - new URL
const myPetImage = new URL(`../assets/pets/${myPet}.png`, import.meta.url).href
// Vite - import.glob
const petImages = import.meta.glob('../assets/pets/*.png', { eager: true })
const myPetImage = petImages[`../assets/pets/${myPet}.png`]
4. Но как работают все эти функции, если тут путь тоже вычисляется только в рантайме, а нужен ещё на этапе сборки?
Сборщик забирает шаблонную строку или конкатенацию строк. Затем считает, что вы можете импортировать в рантайме ЛЮБОЙ файл, подходящий под шаблон. В примерах выше сборщик найдёт все файлы
.png в директории /assets/pets/.Более сложные JS выражения не будут работать.
new URL(getPetImageByName(myPet)) // ❌ Не сработает
Подробности:
- https://vitejs.dev/guide/assets.html
- https://vitejs.dev/guide/features.html#glob-import
- https://webpack.js.org/guides/asset-management/#loading-images
- https://github.com/vitejs/vite/issues/10597
BY Vue.js Feed — Канал русскоговорящего сообщества
Share with your friend now:
tgoop.com/vuejs_ru_feed/34
