如何用Vite动态引入的图片?

摘要:vite官网地址 https:cn.vitejs.devguideassets Vite 默认不支持 require Vite 默认不支持 require, 但可以通过安装 vite-plugin-require-transform
vite官网地址 https://cn.vitejs.dev/guide/assets Vite 默认不支持 require Vite 默认不支持 require, 但可以通过安装 vite-plugin-require-transform 插件来实现。 推荐优先使用 import 方式。 通过@符号和相对路径引入图片 <template> <div class="box"> <div class="img-box" :key="index"> <img :src="demo1" alt=""> </div> <div class="img-box" :key="index"> <img :src="demo2" alt=""> </div> </div> </template> <script setup> // 通过 @符号 和 相对路径(../../)都是可以引入图片的哈 import demo1 from '@/assets/allpng/demo1.png' import demo2 from '../../assets/allpng/demo2.png' </script> <style scoped> .box{ display: flex; } .img-box{ margin-left: 10px; margin-right: 10px; } </style> new URL('url', import.meta.url)动态引入图片 const imgUrl = new URL('./img.png', import.meta.url).href 这个模式同样还可以通过字符串模板支持动态 URL: function getImageUrl(name) { return new URL(`../../${name}.png`, import.meta.url).href } 关于 new URL('url', import.meta.url)的简单说明 import.meta.url 是一个 ESM 的原生功能,会暴露当前模块的 URL。 将它与原生的 URL 构造器组合使用, 通过相对路径我们就能得到一个被完整解析的静态资源 URL Vite 在开发阶段并不需要处理上述代码。 在生产构建时Vite 才会进行必要的转换。保证 URL 在打包后【资源哈希】仍指向正确的地址 这个 URL 字符串必须是静态的,这样才能被分析。 否则代码将被原样保留,进而在 build.target 不支持 import.meta.url 时导致运行时错误。 实践通过 new URL来动态加载图片 <template> <div class="box"> <div class="img-box" v-for="(itemImg,index) in sourceImgList" :key="index"> <img :src="getImgPath(itemImg)" alt=""> </div> </div> </template> <script setup> import { ref } from 'vue' const sourceImgList=ref([ { imgName: 'demo1', }, { imgName: 'demo2', }, { imgName: 'demo3', } ]) function getImgPath(itemImg) { // 这里是可以使用 相对路径的,打包之后,也是没有问题的。 return new URL(`../../assets/allpng/${itemImg.imgName}.png`,import.meta.url).href } </script> <style scoped> .box{ display: flex; } .img-box{ margin-left: 10px; margin-right: 10px; } </style> 打包之后也是可以正常显示的 通过 import.meta.glob 的方式动态引入图片 <template> <div class="box"> <div class="img-box" v-for="(itemImg,index) in sourceImgList" :key="index"> <img :src="getImgPath(itemImg)" alt=""> </div> </div> </template> <script setup> import { ref } from 'vue' const sourceImgList=ref([ { imgName: 'demo1', }, { imgName: 'demo2', }, { imgName: 'demo3', } ]) // 通过 import.meta.glob 的方式引入图片,指向的是src目录, const productAllPngImgObj = import.meta.glob('@/assets/allpng/*.png', { eager: true }) const iconMap = {} for (const path in productAllPngImgObj) { //path的值是 /src/assets/allpng/demo1.png const moduleObj = productAllPngImgObj[path] // 字符串转化为数组,然后取数组的最后一个元素 fileName:demo1.png const fileName = path.split('/').pop() iconMap[fileName] = moduleObj.default //iconMap存储的是这样的格式 { demo1.png : "/src/assets/allpng/demo31.png"} console.log('iconMap', iconMap) } function getImgPath(itemImg) { const imgName = `${itemImg.imgName}.png` return iconMap[imgName] } </script> <style scoped> .box{ display: flex; } .img-box{ margin-left: 10px; margin-right: 10px; } </style> 打包之后图片也是可以正常展示的 在vite中,为什么 new URL() 不支持 @路径来表示 @是构建时的路径别名, new URL() 是浏览器原生的运行API,浏览器运行时完全不知道这个别名。 浏览器只会把它当作普通的相对路径或绝对路径来处理,不会经过 Vite 的模块来解析。