Vue项目中如何从本地JSON文件加载并显示本地图片?
问题描述
我有一个如下结构的JSON文件:
[ { "id": 1, "name": "name1", "img": "pic1.jpg" } ]
在Vue项目中导入该JSON后,我尝试用里面的图片名称绑定img标签的src:
<div v-for="item in countries" :key="item.id"> <img :src="../src/assets/images/`item.img`" alt=""> </div>
但图片无法显示,其他数据都正常加载,请问该怎么正确加载这些图片?
相关代码如下:
Home.vue 脚本
<script> import { useDark, useToggle } from '@vueuse/core' import jsonData from "../data/country.json" export default { name: "Home", setup() { const isDark = useDark(); const toggleDark = useToggle(isDark); console.log(isDark.value); return { isDark, toggleDark } }, data: function () { return { isSideOpen: false, drawer: true, isTheme: false, listView: false, show: false, } }, data() { return { countries: jsonData } }, } </script>
vite.config.js
import { defineConfig } from 'vite'; import laravel from 'laravel-vite-plugin'; import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [ vue(), laravel({ input: [ 'resources/js/app.js'], //worls best without css refresh: true, }), ], });
解决方案
核心问题
你绑定src的方式有误,Vite环境下不能直接用字符串拼接静态资源路径,必须通过Vite提供的API来处理资源引用,否则打包后路径会失效。
方法一:动态生成资源URL(推荐)
修改模板中的img标签,用new URL()结合import.meta.url构建正确的资源路径:
<div v-for="item in countries" :key="item.id"> <img :src="new URL(`../assets/images/${item.img}`, import.meta.url).href" :alt="item.name"> </div>
注意:路径要根据你的项目实际结构调整,比如如果Home.vue在src/views目录下,那么相对src/assets/images的路径就是../assets/images。
方法二:预加载所有图片资源
如果图片数量不多,可以提前批量导入图片资源,再替换JSON中的路径:
- 修改Home.vue的脚本部分:
<script> import { useDark, useToggle } from '@vueuse/core' import jsonData from "../data/country.json" // 批量导入assets/images下的所有jpg图片(按需修改后缀) const imageAssets = import.meta.glob('../assets/images/*.jpg', { eager: true }) export default { name: "Home", setup() { const isDark = useDark(); const toggleDark = useToggle(isDark); console.log(isDark.value); return { isDark, toggleDark } }, data() { // 处理JSON数据,把img字段替换为实际资源路径 const countries = jsonData.map(item => ({ ...item, img: imageAssets[`../assets/images/${item.img}`].default })) // 合并两个data函数的属性,避免原数据被覆盖 return { countries, isSideOpen: false, drawer: true, isTheme: false, listView: false, show: false, } }, } </script>
- 模板中直接绑定处理后的img字段:
<div v-for="item in countries" :key="item.id"> <img :src="item.img" :alt="item.name"> </div>
额外注意事项
- 你的Home.vue里写了两个
data函数,这会导致第一个data里的属性被完全覆盖,必须合并成一个data函数,把所有属性放在同一个返回对象里。 - 确认图片文件确实存在于
src/assets/images目录下,文件名和JSON中的完全一致(Vite环境区分文件名大小写)。
内容的提问来源于stack exchange,提问作者user19367608
相关产品推荐
相关产品推荐

