Vite+React项目中如何通过Props动态拼接路径获取src文件夹内的图片
你在Vite+React项目里尝试通过Props动态拼接图片路径加载src/assets下的图片时遇到了404错误,对吧?就像你写的那样,在Card组件里用src={../assets/imgs/card/${props.img}},然后在App组件传img="img1.svg",结果控制台报找不到资源,但直接用import导入图片再赋值给src就正常工作。
这是因为Vite的静态资源处理逻辑导致的——Vite在构建时需要明确知道哪些静态资源要被打包,动态拼接的路径属于运行时生成的内容,Vite没办法在构建阶段解析这些路径,也就不会把对应的图片纳入打包流程,所以运行时自然找不到文件。哪怕你写死路径,如果不是通过import或者Vite能识别的方式引用,也会出现同样的问题。
解决方案1:使用import.meta.glob批量导入图片
这是最推荐的方式,既能保留动态传参的灵活性,又能让Vite正确处理静态资源优化。
在你的Card组件里,先批量导入目标文件夹下的所有图片:
// 批量导入../assets/imgs/card下的所有svg文件,eager设为true表示立即导入 const cardImages = import.meta.glob('../assets/imgs/card/*.svg', { eager: true, import: 'default' // 导入默认导出(即图片的路径) });
然后在img标签里通过props的文件名匹配对应的图片:
<img className={cardCss.card__img} src={cardImages[`../assets/imgs/card/${props.img}`]} alt="Card image" />
这样Vite在构建时会把所有匹配的图片都打包,运行时就能通过拼接的路径找到对应的资源了。
解决方案2:将图片移到public文件夹
如果你不想用批量导入,也可以把图片放到项目根目录的public文件夹下(没有的话可以新建),比如放到public/assets/imgs/card/。
然后修改img的src为绝对路径拼接:
<img className={cardCss.card__img} src={`/assets/imgs/card/${props.img}`} alt="Card image" />
public文件夹里的资源会被Vite原样复制到打包后的根目录,所以直接用绝对路径就能访问。不过这种方式Vite不会对图片做压缩、按需加载等优化,适合对资源体积要求不高的场景。
解决方案3:父组件导入图片后传参
如果你的图片数量不多,也可以在父组件(比如App)里提前导入所有需要的图片,然后把导入后的变量作为props传给Card组件:
在App组件里:
import img1 from "../assets/imgs/card/img1.svg"; import img2 from "../assets/imgs/card/img2.svg"; function App() { return ( <div> <Nav /> <Main /> <Card img={img1} /> <Card img={img2} /> </div> ); }
然后Card组件直接用props.img作为src即可:
<img className={cardCss.card__img} src={props.img} alt="Card image" />
这种方式简单直接,缺点是图片多的话会比较繁琐。
优先推荐方案1,它平衡了动态性和Vite的资源优化能力;如果资源不多,方案3也很省心;方案2适合快速测试或者不需要优化的场景。
备注:内容来源于stack exchange,提问作者Shruti Kolla

