Uncaught (in promise) Error: Unknown variable dynamic import:at dynamic-import-helper:7:96at new Promise (<anonymous>)
变量形式的动态 import(),但 Vite 在运行时找不到这个变量对应的模块路径,所以 Promise 被 reject 了,浏览器就报了 Uncaught (in promise)。
修复后的代码
<template>
<canvas
ref="animationCanvas"
class="animation_canvas"
id="animation_canvas"
></canvas>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, nextTick, watch } from 'vue'
const props = defineProps({
fileLength: {
type: Number,
default: 124
},
IntervalTime: {
type: Number,
default: 50
},
startAnimation: {
type: Boolean,
default: true
}
})
const animationCanvas = ref(null)
const imagesLoaded = ref(false)
let stopPlayer = null
const imageModules = import.meta.glob('./bg/*.png', {
eager: true,
import: 'default'
})
const getImageSources = () => {
const sources = []
for (let i = 0; i <= props.fileLength; i++) {
const path = `./bg/${i}.png`
if (imageModules[path]) {
sources.push(imageModules[path])
} else {
console.warn(`[animation] 图片不存在: ${path}`)
}
}
return sources
}
const loadImages = (sources) => {
return new Promise((resolve) => {
let loadedImages = 0
const numImages = sources.length
const images = []
if (!numImages) {
resolve([])
return
}
for (let i = 0; i < numImages; i++) {
images[i] = new Image()
images[i].onload = () => {
loadedImages++
if (loadedImages >= numImages) {
resolve(images)
}
}
images[i].onerror = () => {
loadedImages++
console.warn(`[animation] 加载失败: ${sources[i]}`)
if (loadedImages >= numImages) {
resolve(images.filter(Boolean))
}
}
images[i].src = sources[i]
}
})
}
const playImages = (images, ctx, width, height, intervalTime) => {
let imageNow = 0
const drawCurrentFrame = () => {
if (!images.length) return
ctx.clearRect(0, 0, width, height)
ctx.drawImage(images[imageNow], 0, 0, width, height)
imageNow = (imageNow + 1) % images.length
}
drawCurrentFrame()
const timer = setInterval(() => {
if (!props.startAnimation) return
drawCurrentFrame()
}, intervalTime)
return () => clearInterval(timer)
}
onMounted(async () => {
await nextTick()
const canvas = animationCanvas.value
if (!canvas) return
const ctx = canvas.getContext('2d')
if (!ctx) {
console.error('Failed to get canvas context')
return
}
const width = canvas.offsetWidth
const height = canvas.offsetHeight
canvas.width = width
canvas.height = height
const sources = getImageSources()
if (!sources.length) {
console.error('未找到任何动画图片,请检查 ./bg/ 目录')
return
}
const firstImgElement = new Image()
firstImgElement.src = sources[0]
firstImgElement.onload = () => {
ctx.clearRect(0, 0, width, height)
ctx.drawImage(firstImgElement, 0, 0, width, height)
}
const images = await loadImages(sources)
imagesLoaded.value = true
if (props.startAnimation && images.length) {
stopPlayer = playImages(images, ctx, width, height, props.IntervalTime)
}
})
watch(
() => props.IntervalTime,
() => {
if (stopPlayer) {
stopPlayer()
stopPlayer = null
}
}
)
onBeforeUnmount(() => {
if (stopPlayer) {
stopPlayer()
stopPlayer = null
}
})
</script>
<style scoped>
.animation_canvas {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: -1;
}
</style>