Objective

我想将图像的path作为props 传递给组件.我希望组件使用props 来动态生成背景图像.

我的所有图像都在Vue src文件夹中的Assets文件夹中. 路径看起来像'@/assets/images/subject/computers.jpeg'

Problem

未显示任何背景图像

以下是页面上呈现的内容:

enter image description here

然而,什么也没有显示出来

Strange Behaviour

出于某种原因,在CSS中添加完全相同的路径名'@/assets/images/subject/computers.jpeg'是可行的(将其添加到<style>标记中).如果它是V-BIND内联风格,它就不起作用.

下面是它在我的css中的样子

enter image description here

然而,这样做的问题是它不是动态呈现的CSS.

我进一步判断了这个元素,发现了一些奇怪的行为.如您所见,内联样式将图像路径读取为'@/assets/images/subject/computers.jpeg'(下图中的element.style).

而在css中添加路径时,会将'@/assets/images/subject/computers.jpeg'更改为'http://localhost:8080/img/computers.7f3748eb.jpeg',从而正确呈现背景图像.

enter image description here

Question

我想我的问题有两个方面:

  1. 如何使用props 在Vue中动态渲染背景图像?或者,有没有更好的方法来做到这一点?
  2. 为什么绑定内联样式不解析路径(继续使用‘@’),而直接将其添加到<脚本>标记中可以解析路径?

Solution

好的,非常感谢100&101帮助我思考这件事.

我能够使用如下所示的计算(computed)属性解决此问题:

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

由于VueLoader(Vue中的默认设置)解析路径的方式,我无法将‘@’路径存储在props 本身中.相反,props 只是图像/文件名(ex. "computers.jpeg"),而带有Required()的Computed属性负责解析图像的前置路径.

然后,我将计算(computed)属性添加到绑定内联样式中,如下所示:

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

瞧啊!它终于奏效了.

TLDR

将图像/文件名作为props 传递100,并在计算(computed)属性中使用Require()为路径添加前缀.

干杯????

推荐答案

使用webpack(Vue-cli)时,@符号是src文件夹的别名.

如果URL以@开头,它也会被解释为模块请求.如果您的webpack配置有@的别名,这将非常有用,该别名默认指向由vue-cli创建的任何项目中的/src

Source

如果您使用的是vite,则在vite.config.js中可能有以下内容;

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

当资源URL位于以下html标签中时,VueLoader会对其进行转换:videosourceimgimage(Svgs)和use(Svg).此外,如果您将VueLoader配置为使用css-loader,它还会转换标记中的资源URL.

所有编译后的css都由css加载器处理,css加载器解析url()并将其解析为模块请求.

Source

当您对样式属性进行v绑定时,不会发生此资源URL转换.

您可以使用此机制将转换后的路径传递到不同的组件(例如,库中的组件).尽管如此,您仍然需要声明@道提到的每一条路径.

这里相关的一点是,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还提到的,如果不同图像的数量太多,您可以 Select 将这些图像放置在项目的public个文件夹中.

编辑:您也可以使用带有if-else树、ternaryswitch语句的require方法来获取图像的相对路径(如果可以设置为背景的图像数量不是太多-否则使用public文件夹).

对于Vite,您可以使用vite-plugin-require插件来使require()工作.

Css相关问答推荐

如何以Angular 将下拉面板的宽度与其文本框对齐

为什么我的容器的弹性包裹会导致我的自动填充网格添加额外的空轨道行?

创建始终为剪辑元素的300%高度并左对齐的圆形剪辑路径

在最小和最大视口之间时具有固定值的 CSS 钳位

如何使用 Ant Design 为不同的屏幕尺寸制作自定义组件样式

包含 N 个 React 组件的砌体网格

有没有办法将px单位添加到 Sass mixin 的参数数组中?

CSS 网格 - 具有独立可滚动区域的两列布局

在 React Native 中创建背景

使用 css 网格和 nth-child 交替行

css渐变实现2色虚线边框

从 Angular SCSS 生成 CSS?

为什么标题中的特定 div 与 Odoo 13 中 PDF 中的页面重叠?

reactjs - 容器中水平行的png图像

Angular Material 中的样式垫 Select

如何在 html/css 中的图像旁边垂直居中文本?

如何使用 Gulp 复制多个文件并保持文件夹 struct

通过javascript删除或禁用浏览器的焦点边框

:before 和 ::before 有什么区别?

HTML浮动右元素顺序