Jer*_*ung 5 css data-binding vue.js vue-props vue-composition-api
客观的
我想将图像的路径作为道具传递给组件。我希望组件使用 prop 来动态生成背景图像。
我的所有图像都位于 Vue src 文件夹中的 asset 文件夹中。该路径看起来像“@/assets/images/subject/computers.jpeg”
问题
没有背景图像出现
这是页面上呈现的内容:
然而,什么也没有出现
奇怪的行为
由于某种原因,在 CSS 中添加完全相同的路径名“@/assets/images/subject/computers.jpeg”是可行的(将其添加到 <style> 标签中)。如果它是 v-bind 内联样式,它就不起作用。
这是我的 CSS 中的样子
但问题是它不是动态渲染的 CSS。
我进一步检查了该元件并发现了一些奇怪的行为。如您所见,内联样式将图像路径读取为“@/assets/images/subject/computers.jpeg”(下图中的 element.style)。
在 CSS 中添加路径时,将'@/assets/images/subject/computers.jpeg'更改为'http://localhost:8080/img/computers.7f3748eb.jpeg',然后正确渲染背景图像。
问题
我想我的问题是双重的:
解决方案
好的,非常感谢tao和Bernard Borg帮助我解决了这个问题。
我能够使用计算属性来解决这个问题,如下所示:
const imgSrc = computed(() => require(`@/assets/images/subject/${props.subject.image}`))
Run Code Online (Sandbox Code Playgroud)
由于 VueLoader(Vue 中的默认设置)解析路径的方式,我无法将“@”路径存储在 prop 本身中。相反,该 prop 只是图像/文件名(例如“computers.jpeg”),并且使用 require() 的计算属性处理解析图像的前置路径。
之后,我将计算属性添加到绑定的内联样式中,如下所示:
<div class="subject-wrapper" v-bind:style="{ backgroundImage: `url('${imgSrc}')` }">
Run Code Online (Sandbox Code Playgroud)
瞧!它终于起作用了。
总长DR
仅传递图像/文件名作为 prop,并在计算属性中使用 require() 在路径前面添加路径。
干杯
使用 Webpack (Vue-cli) 时,该@
符号是 src 文件夹的别名。
如果 URL 以 @ 开头,它也会被解释为模块请求。如果您的 webpack 配置有 @ 别名,则这很有用,默认情况下它指向 vue-cli 创建的任何项目中的 /src
如果你使用 Vite,你可能在 vite.config.js 中有以下内容;
resolve: {
alias: {
"@": fileURLToPath(new URL("./src", import.meta.url)),
...
}
}
Run Code Online (Sandbox Code Playgroud)
当资源 URL 位于以下 html 标签中时,VueLoader 会对其进行转换:video
、source
、img
、image
(svgs) 和use
(svgs)。此外,如果您将 VueLoader 配置为使用css-loader
.
所有编译的 CSS 都由 css-loader 处理,它解析 url() 并将它们解析为模块请求。
当您 v 绑定样式属性时,不会发生此资源 URL 转换。
您可以使用此机制将转换后的路径传递到不同的组件(例如,库中的组件)。尽管如此,您仍然需要声明 @tao 提到的每条路径。
这里相关的一点是,VueLoader 在编译应用程序时必须读取所有可能的路径并解析它们。
<script setup lang="ts">
import BackgroundImageViewer from './components/BackgroundImageViewer.vue'
import { ref, onMounted } from "vue";
const hiddenImage = ref<HTMLImageElement>();
const thePath = ref();
onMounted(() => {
if (hiddenImage.value) {
thePath.value = hiddenImage.value.src;
hiddenImage.value.src = "";
}
});
</script>
<template>
<img src="@/assets/vue.svg" ref="hiddenImage" hidden />
<BackgroundImageViewer :path="thePath"/>
</template>
Run Code Online (Sandbox Code Playgroud)
正如@tao 还提到的,如果不同图像的数量太多,您可以选择将图像放置在项目的public
文件夹中。
编辑:您还可以使用require
带有if-else
树ternary
或switch
语句的方法来获取图像的相对路径(如果可以设置为背景的图像数量不是太多 - 否则使用文件public
夹)。
有了Vite
你就可以使用vite-plugin-require
插件来进行require()
工作了。