【问题标题】:How to create a dynamic background image for components in Vue using props?如何使用道具为 Vue 中的组件创建动态背景图像?
【发布时间】:2023-01-30 02:47:11
【问题描述】:

客观的

我想通过小路图像作为组件的道具。我希望组件使用 prop 动态生成背景图像。

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

问题

没有出现背景图像

这是页面上呈现的内容:

但是,没有任何显示

奇怪的行为

出于某种原因,添加完全相同的路径名'@/assets/images/subject/computers.jpeg'在 CSS 中工作(将其添加到 <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',然后正确呈现背景图像。

问题

我想我的问题是双重的:

  1. 您将如何使用道具在 Vue 中动态渲染背景图像?或者有更好的方法吗?
  2. 为什么绑定内联样式不解析路径(一直使用“@”),而直接将其添加到 <script> 标签中却解析路径?

【问题讨论】:

  • 在引擎盖下,Vue 使用 VueLoader 来根据环境解析正确的资产路径(它在服务(开发)和构建(生产)时具有不同的路径)。阅读Asset URL Handling。具体来说,转换规则.

标签: css vue.js data-binding vue-composition-api vue-props


【解决方案1】:

使用 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(svgs)。此外,如果您将 VueLoader 配置为使用 css-loader,它还会转换位于标签中的资产 URL。

所有编译的 CSS 都由 css-loader 处理,它解析 url() 并将它们解析为模块请求。

Source

当您 v-binding 样式属性时,不会发生此资产 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 文件夹中。

【讨论】:

  • 保持动态资产 URL 跨环境工作以及在服务器文件夹内服务的应用程序中工作的正确方法是使用 require(),它与相对路径一起工作。示例:const bgSrc = computed(() =&gt; condition ? require('pathA') : require('pathB'))。使用location.origin 打破了很多用例。
  • 好的 - 你指的是什么条件?
  • 任何条件。请阅读您正在回答的问题的标题。
  • 如果有无限的选择怎么办?
  • 那是无关紧要的。使用switch。这里的相关点是 VueLoader 必须读取所有可能的路径在编译应用程序并解决它们时。我猜有人希望他们的应用程序在部署时能够正常工作。让它只在服务时工作是毫无意义的。
猜你喜欢
  • 2020-07-06
  • 1970-01-01
  • 1970-01-01
  • 2018-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-24
相关资源
最近更新 更多