vite动态引入图片

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 的模块来解析。