Vite / Vue 3:使用图像源作为道具时“未定义要求”

Don*_*ony 41 javascript vue.js vite

我从 Vue CLI 切换到Vite CLI,从 Vue 3 的 Composition API 切换到SFC Script setup API。

以前对我来说效果如何

当我使用官方 Vue CLI 时,我可以通过 props 传递路径的文件名来导入图像源:

<template>
  <img :src="require(`@/assets/${imagePath}`)"/>
<template/>

<script>
export default {
  props: {
    imagePath: { type: String },
  },
  setup() {
    // ...
  }
}
<script/>
Run Code Online (Sandbox Code Playgroud)

然后这样称呼它:

<template>
  <Image imagePath="icon.png" />
</template>
Run Code Online (Sandbox Code Playgroud)

迁移到Vite后出现的错误

但自从我迁移到Vite CLI后,出现了“Uncaught ReferenceError: require is not Defined”的错误。我的文件现在使用脚本设置语法,如下所示:

<script setup>
const props = defineProps({
  imagePath: { type: String },
})
</script>

<template>
  <img :src="require(`@/assets/${props.imagePath}`)"/>
</template>
Run Code Online (Sandbox Code Playgroud)

要求未定义错误

我尝试过的

我已经尝试使用相对路径直接从资产文件夹导入文件,并且它有效。但我无法使用 import 语句指定 props 的路径。

<script setup>
// Works but do not use the props, so the component is not reusable
import logo from "./../assets/logo.png"
</script>

<template>
  <img :src="logo"/>
</template>
Run Code Online (Sandbox Code Playgroud)
<script setup>
// Component is reusable but the import statement has illegal argument I guess
const props = defineProps({
  imagePath: { type: String },
})

import logo from `./../assets/${props.imagePath}`
</script>

<template>
  <img :src="logo"/>
</template>
Run Code Online (Sandbox Code Playgroud)

我还尝试了模板中的 import 语句,但它甚至无法编译代码:

<script setup>
const props = defineProps({
  imagePath: { type: String },
})
</script>

<template>
  <img :src="import `./../assets/${props.iconPath}`" />
</template>
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?也许有一个插件可以帮助我实现这一目标?

lei*_*ipz 51

我也遇到了这个问题。我搜索了这个并根据这个github问题评论发现,

require使用 Vite 时,源代码中绝对不应该有。这只是 ESM。

有关此内容的更多信息,请参阅功能 | Vite - 静态资源

经过一番搜索,我找到了这个对我有用的Vue 3 代码示例链接

<CarouselItem v-for="(item,index) of carouselData" :key="index">
 <img :src="getImageUrl(item.img_name)" />
</CarouselItem>
Run Code Online (Sandbox Code Playgroud)
setup() {
  const getImageUrl = (name) => {
        return new URL(`../../lib/Carousel/assets/${name}`, import.meta.url).href
    }
  return { carouselData, getImageUrl }
}
Run Code Online (Sandbox Code Playgroud)


Art*_*nov 13

如果您正在使用require.context,新方法似乎是glob import。将您的旧声明更改为:

const locales = require.context("../../lang", true, /[A-Za-z0-9-_,\s]+\.json$/i)
Run Code Online (Sandbox Code Playgroud)

到:

const locales = import.meta.glob('../../lang/*.json')
Run Code Online (Sandbox Code Playgroud)

编辑

这似乎也取代了require


ton*_*y19 1

在动态导入图像的 prop上使用观察者,并用结果更新 a (绑定到):imagePathref<img>.src

<script setup>
import { ref, watchEffect } from 'vue'

const props = defineProps({
  imagePath: { type: String },
})

const logo = ref()
watchEffect(async () => {
  logo.value = (await import(/* @vite-ignore */ `../assets/${props.imagePath}`)).default
})
</script>

<template>
  <img :src="logo">
</template>
Run Code Online (Sandbox Code Playgroud)

演示