如何使用 prop 为Vue中的组件创建动态背景图像?

mzsu5hc0  于 2023-01-31  发布在  Vue.js
关注(0)|答案(1)|浏览(154)
    • 目标**

我想把一个图片的路径作为 prop 传递给一个组件。我想让组件使用这个 prop 来动态生成背景图片。
Vue src文件夹下的assets文件夹中的所有图像。路径类似于"'@/assets/images/subject/computers. jpeg'*

    • 问题**

不显示背景图像
这是页面上呈现的内容:

但是,没有显示任何内容
"奇怪的行为"
出于某种原因,在CSS中添加完全相同的路径名 *'@/assets/images/subject/computers. jpeg'*可以(在标记中添加),但如果是v-bind内联样式,就不行了。 tags). It just doesn't work if it's v-bind inline style.
下面是它在我的CSS中的样子

但问题是,它不是动态呈现的CSS。
我进一步检查了这个元素,发现了一些奇怪的行为,正如你所看到的,内联样式读取图像路径为 '@/assets/images/subject/computers. jpeg'(下图中的element.style)。
在CSS中添加路径时,会将 *'@/assets/images/subject/computers. jpeg'*更改为 'http://localhost:8080/img/computers.7f3748eb.jpeg',这样就可以正确地呈现背景图像。

    • 问题**

我想我的问题有两个:
1.如何在Vue中用 prop 动态渲染背景图像?或者有更好的方法吗?
1.为什么绑定内联样式不解析路径(一直使用"@"),而直接在标记中添加它却解析路径? tags does resolve the path?

    • 解决方案**

好的,非常感谢***陶***和***伯纳德·博格***帮助我理解这一点。
我可以使用如下计算属性来解决这个问题:

const imgSrc = computed(() => require(`@/assets/images/subject/${props.subject.image}`))

由于VueLoader(Vue中的默认设置)解析路径的方式,我无法将"@"路径存储在prop本身中,而prop只是图像/文件名 (例如"computers.jpeg"),并且require()的computed属性负责解析图像的前置路径。
之后,我将computed属性添加到绑定的内联样式中,如下所示:

<div class="subject-wrapper" v-bind:style="{ backgroundImage: `url('${imgSrc}')` }">

瞧终于成功了。

    • 顶级域名注册商**
      ***仅***将图像/文件名作为prop传递,并在computed属性中使用require()将路径作为前缀。

干杯🍻

hc8w905p

hc8w905p1#

使用Webpack(Vue-cli)时,@符号是src文件夹的别名。
如果URL以@开头,它也会被解释为模块请求。如果您的webpack配置中有@的别名,这将非常有用,在vue-cli创建的任何项目中,该别名默认指向/src
来源
如果您使用的是Vite,那么vite.config.js中可能包含以下内容;

resolve: {
     alias: {
          "@": fileURLToPath(new URL("./src", import.meta.url)),
          ...
     }
}

当资产URL位于以下html标签中时,VueLoader会转换资产URL:videosourceimgimage(svgs)和use(svgs)。此外,如果您将VueLoader配置为使用css-loader,则它还会转换标记中的资产URL。
所有编译的CSS都由css-loader处理,它解析url()并将它们解析为模块请求。
Source
当你对一个样式属性进行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>

正如@tao提到的,如果不同图片的数量太多,你可以选择将图片放在你项目的public文件夹中。
编辑:您也可以使用require方法和if-else树、ternaryswitch语句来获取图像的相对路径(如果可以设置为背景的图像数量不是太多-否则使用public文件夹)。
通过Vite,您可以使用vite-plugin-require插件来使require()工作。

相关问题