Vue+TypeScript从assets加载图片到Canvas遇404错误求解决方案
解决Vue+TypeScript中从Assets加载图片到Canvas的404问题
问题原因
Vue项目里src/assets目录下的资源会被Webpack编译处理,编译后文件会被重命名(通常添加哈希值)并输出到指定目录。直接用字符串路径/assets/1.jpg时,浏览器会请求根目录下的assets文件夹,但这个路径和编译后的实际资源路径不匹配,所以出现404错误。
可行解决方案
方案1:用require获取编译后路径
通过require导入图片资源,Webpack会自动解析并返回编译后的正确URL。修改代码如下:
<template> <canvas id="CanvasTest" width="800" height="600"></canvas> </template> <script lang="ts"> import { defineComponent } from 'vue'; export default defineComponent({ name: 'CanvasTest', data() { return { images_src: [ require('@/assets/1.jpg'), require('@/assets/2.jpg'), require('@/assets/3.jpg') ] } }, mounted() { const canvas = document.getElementById('CanvasTest') as HTMLCanvasElement; const ctx = canvas.getContext("2d") as CanvasRenderingContext2D; const img_w = 200; const img_h = 100; for (let i = 0; i < this.images_src.length; i++) { const imgElement = new Image(); imgElement.src = this.images_src[i]; imgElement.onload = () => { ctx.drawImage(imgElement, i*img_w, i*img_h, img_w, img_h); }; } }, }); </script> <style> #CanvasTest { background-color: #555; } </style>
方案2:用import静态导入图片
在脚本顶部直接导入图片资源,把导入后的变量作为图片路径使用,适合明确知道要加载的图片列表的场景:
<template> <canvas id="CanvasTest" width="800" height="600"></canvas> </template> <script lang="ts"> import { defineComponent } from 'vue'; // 静态导入图片 import img1 from '@/assets/1.jpg'; import img2 from '@/assets/2.jpg'; import img3 from '@/assets/3.jpg'; export default defineComponent({ name: 'CanvasTest', data() { return { images_src: [img1, img2, img3] } }, mounted() { const canvas = document.getElementById('CanvasTest') as HTMLCanvasElement; const ctx = canvas.getContext("2d") as CanvasRenderingContext2D; const img_w = 200; const img_h = 100; for (let i = 0; i < this.images_src.length; i++) { const imgElement = new Image(); imgElement.src = this.images_src[i]; imgElement.onload = () => { ctx.drawImage(imgElement, i*img_w, i*img_h, img_w, img_h); }; } }, }); </script> <style> #CanvasTest { background-color: #555; } </style>
方案3:Vue 3+中使用resolveUrl(适配Vite/Webpack)
如果是Vue 3项目,可以用Vue提供的resolveUrl方法结合import.meta.url解析资源路径,适合动态路径场景:
<template> <canvas id="CanvasTest" width="800" height="600"></canvas> </template> <script lang="ts"> import { defineComponent, resolveUrl } from 'vue'; export default defineComponent({ name: 'CanvasTest', data() { return { images_src: ['/assets/1.jpg', '/assets/2.jpg', '/assets/3.jpg'] } }, mounted() { const canvas = document.getElementById('CanvasTest') as HTMLCanvasElement; const ctx = canvas.getContext("2d") as CanvasRenderingContext2D; const img_w = 200; const img_h = 100; for (let i = 0; i < this.images_src.length; i++) { const imgElement = new Image(); // 解析正确路径 imgElement.src = resolveUrl(this.images_src[i], import.meta.url); imgElement.onload = () => { ctx.drawImage(imgElement, i*img_w, i*img_h, img_w, img_h); }; } }, }); </script> <style> #CanvasTest { background-color: #555; } </style>
注意事项
- 只有通过
import或require引入的assets资源才会被Webpack处理并打包,直接用字符串路径无法触发资源编译,导致路径无效。 @是Vue项目中配置的src目录别名,若未配置可改用相对路径(如../assets/1.jpg)。
内容的提问来源于stack exchange,提问作者Likor
相关产品推荐
相关产品推荐

