生产版本中的图像路径不正确 - Vue.js

Incorrect images path in production build - Vue.js

我正在使用 Vue.js 3、Vite.js 构建我的项目。 该应用程序在开发模式下(使用开发服务器时)运行良好。一旦我启动构建命令,Vite 就会为我创建 /dist 目录,其中包含我的应用程序的构建。如果我 运行 预览命令 (vite preview) 它可以毫无问题地启动我的构建预览。

问题出在一些来自 Vue 组件的图像上。我项目的所有图像都在 src/assets 目录中。

.
├── Attribution.txt
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│   └── favicon.ico
├── src
│   ├── App.vue
│   ├── assets
│   │   ├── Temp.png
│   │   ├── bridge.png
│   │   ├── city-security.png
│   │   ├── credit-card.png
│   │   ├── deforestation.png
│   │   ├── eagle.png
│   │   ├── favicon
│   │   │   ├── android-chrome-192x192.png
│   │   │   ├── android-chrome-512x512.png
│   │   │   ├── apple-touch-icon.png
│   │   │   ├── favicon-16x16.png
│   │   │   ├── favicon-32x32.png
│   │   │   └── favicon.ico
│   │   ├── global-goals.png
│   │   ├── hall.png
│   │   ├── italian-flag.png
│   │   ├── machine-learning.png
│   │   ├── modern-architecture.png
│   │   ├── moon-festival.png
│   │   ├── people.png
│   │   ├── planet-earth.png
│   │   ├── police.png
│   │   ├── teamwork.png
│   │   ├── uk-flag.png
│   │   └── virtual.png
│   ├── components
│   │   ├── Button.vue
│   │   ├── Card.vue
│   │   ├── Column.vue
│   │   ├── Footer.vue
│   │   ├── MainContent.vue
│   │   ├── Navbar.vue
│   │   └── components-it
│   │       ├── Card-it.vue
│   │       ├── Footer-it.vue
│   │       └── Navbar-it.vue
│   ├── main.js
│   ├── router
│   │   └── index.js
│   ├── tailwind.css
│   └── views
│       ├── CitySecurity.vue
│       ├── Contribute.vue
│       ├── Credits.vue
│       ├── Goals.vue
│       ├── Home.vue
│       ├── It
│       │   ├── CitySecurity-it.vue
│       │   ├── Contribute-it.vue
│       │   ├── Credits-it.vue
│       │   ├── Goals-it.vue
│       │   ├── Home-it.vue
│       │   └── Municipality-it.vue
│       └── Municipality.vue
├── tailwind.config.js
└── vite.config.js

视图中的图像具有正确的路径并在构建中正确显示。但是components文件夹下的图片有问题:构建文件中的路径没有改变

<template>
  <Navbar />
  <div class="container flex flex-col items-center py-20 font-bold mx-auto">
    <h1 class="uppercase text-3xl">A new way to live the City</h1>
    <img src="../assets/hall.png" alt="Town Hall" width="250" class="py-10" />
    <p class="lg:w-1/2 text-justify leading-relaxed">
      To improve the municipality livings being we tought about some ideas, that
      are somehow able to improve the qol(Quality of life). One of the most
      reliable problem that requires to be solved is the minimization of
      burocracy, tryna to make things digital any sort of procedure. One of ours
      ideas is to improve the mechanism of shifting around the city, by giving
      cityzens public and shareble veichles to reduce pollution and the waste of
      fuel.
    </p>
    <div class="grid lg:grid-cols-3 lg:gap-0 gap-10 place-items-center pt-20">
      <div class="card container flex flex-col items-center justify-center">
        <h1 class="uppercase text-xl">Digitalization</h1>
        <img
          class="py-5"
          src="../assets/virtual.png"
          alt="Digitalization"
          width="100"
        />
        <p class="lg:w-full text-justify lg:w-3/5 lg:leading-relaxed w-3/4">
          Burocracy is so annoying, so we tought about how we can semplify it.
          The Answer is... DIGITALIZATION! Everything's simpler when digital, so
          our city is going to have a system for all of them.
        </p>
      </div>
      <div class="card container flex flex-col items-center justify-center">
        <h1 class="uppercase text-xl">Infrastructures Upgrading</h1>
        <img
          class="py-5"
          src="../assets/bridge.png"
          alt="Digitalization"
          width="100"
        />
        <p class="lg:w-full text-justify lg:w-3/5 lg:leading-relaxed w-3/4">
          To make our city better, our city is going to invest in
          infrastructures to let cityzens live their life much better. Better
          "bridges" makes better people.
        </p>
      </div>
      <div class="card container flex flex-col items-center justify-center">
        <h1 class="uppercase text-xl">Innovative Learning</h1>
        <img
          class="py-5"
          src="../assets/Machine-Learning.png"
          alt="Digitalization"
          width="100"
        />
        <p class="lg:w-full text-justify lg:w-3/5 lg:leading-relaxed w-3/4">
          Our city is going to offer a learning system to make everyone learn
          about technologies and new innovation. The mind of a man is the most
          precious part of him.
        </p>
      </div>
    </div>
  </div>
  <Footer />
</template>

<script>
import Navbar from "../components/Navbar.vue";
import Footer from "../components/Footer.vue";
import Button from "../components/Button.vue";
export default {
  name: "Municipality",
  components: {
    Navbar,
    Footer,
    Button,
  },
};
</script>

<style></style>

这是我的一个观点。在构建中,所有 img 标签都将具有正确的路径(例如:/assets/imgName.randomNumbersAndString.png)。

但这不会发生在组件中。

即- Card.vue 组件

<template>
  <div
    class="card container flex flex-col items-center justify-center pt-20 pb-20"
  >
    <a :href="`${link}`">
      <img
        :class="`${imgClass || 'py-5'}`"
        :src="`./src/assets/${imgName}`"
        :alt="`${imgAlt}`"
        width="100"
      />
    </a>
    <p class="lg:w-full lg:w-3/5 lg:leading-relaxed w-3/4">{{ text }}</p>
  </div>
</template>

<script>
export default {
  name: "Card",
  props: {
    link: String,
    imgClass: String,
    imgName: String,
    imgAlt: String,
    text: String,
  },
};
</script>

<style scoped></style>

Credits.vue 查看

<template>
  <Navbar />
  <h1 class="uppercase lg:text-5xl text-2xl mx-auto text-center pt-20">
    Images and Icons attributions
  </h1>
  <div class="grid lg:grid-cols-3 place-items-center lg:pb-10 mx-auto">
    <Card
      link="Hall icons created by Smashicons - Flaticon"
      text="Hall icons created by Smashicons - Flaticon"
      imgAlt="Hall vector representation"
      imgName="hall.png"
    />
    <Card
      link="https://www.flaticon.com/free-icons/moon-festival"
      text="Pokemon icons created by Roundicons Freebies - Flaticon"
      imgAlt="Temp logo"
      imgName="Temp.png"
    />
    <Card
      link="https://www.flaticon.com/free-icons/moon-festival"
      text="Moon festival icons created by Flat Icons - Flaticon"
      imgAlt="Moon vector representation"
      imgName="moon-festival.png"
    />
    <Card
      link="https://www.flaticon.com/free-icons/digital"
      text="Digital icons created by Freepik - Flaticon"
      imgAlt="Digital vector representation"
      imgName="virtual.png"
    />
    <Card
      link="https://www.flaticon.com/free-icons/tower-bridge"
      text="Tower bridge icons created by Freepik - Flaticon"
      imgAlt="Bridge vector representation"
      imgName="bridge.png"
    />
    <Card
      link="https://www.flaticon.com/free-icons/machine-learning"
      text="Machine learning icons created by Flat Icons - Flaticon"
      imgAlt="Machine learning vector representation"
      imgName="machine-learning.png"
    />
    <Card 
      link="https://www.flaticon.com/free-icons/business-and-finance"
      text="Business and finance icons created by Freepik - Flaticon"
      imgAlt="City security vector"
      imgName="city-security.png"
    />
    <Card 
      link="https://www.flaticon.com/free-icons/credit-card"
      text="Credit card icons created by Freepik - Flaticon"
      imgAlt="Credit card vector"
      imgName="credit-card.png"
    />
    <Card 
      link="https://www.flaticon.com/free-icons/deforestation"
      text="Deforestation icons created by Freepik - Flaticon"
      imgAlt="Deforestation vector representation"
      imgName="deforestation.png"
    />
    <Card 
      link="https://www.flaticon.com/free-icons/eagle"
      text="Eagle icons created by Freepik - Flaticon"
      imgAlt="Eagle vector"
      imgName="eagle.png"
    />
    <Card 
      link="https://www.flaticon.com/free-icons/modern-architecture"
      text="Modern architecture icons created by Freepik - Flaticon"
      imgAlt="Modern architecture vector"
      imgName="modern-architecture.png"
    />
    <Card 
      link="https://www.flaticon.com/free-icons/environment"
      text="Environment icons created by Freepik - Flaticon"
      imgAlt="Earth planet vector"
      imgName="planet-earth.png"
    />
  </div>
  <div class="container mx-auto flex flex-row items-center justify-center text-center">
    <Card 
      link="https://www.flaticon.com/free-icons/police"
      text="Police icons created by Freepik - Flaticon"
      imgAlt="Police officer vector"
      imgName="police.png"
    />
    <Card 
      link="https://www.flaticon.com/free-icons/collaboration"
      text="Collaboration icons created by Freepik - Flaticon"
      imgAlt="Community vector"
      imgName="teamwork.png"
    />
  </div>
  <Footer />
</template>

<script>
import Card from "../components/Card.vue";
import Navbar from "../components/Navbar.vue";
import Footer from "../components/Footer.vue";
import Button from "../components/Button.vue";

export default {
  name: "Credits",
  components: {
    Navbar,
    Footer,
    Button,
    Card,
  },
};
</script>

<style scoped></style>

在这种情况下,当我将 imgName 传递给 Card 组件时,在构建文件中图像的路径是 ./src/assets/name.png.

我该如何解决?

您可以使用任何 vue 组件中的 @/assets 来引用资产文件夹中的文件,而不是使用资产文件夹的相对路径 (..)

例如,无论 Vue 组件嵌套多深,这都应该有效。

<img src="@/assets/images/name.png"/>

编辑:

正如 @flydev 指出的那样,您必须像这样配置 vite 配置: 才能正常工作。

问题是,您将文件名作为 属性 传递给组件。组件中的完整图像路径将从路径和可变文件名中导出。然而,这样的动态路径是不可能的,因为所有导入路径都需要在构建时定义。使用您的组件,理论上您可以通过例如来自远程服务器的字符串或随机字符串作为文件名,因此 Vite 在构建期间没有机会找到这些图像。

虽然这个问题的解决方案非常简单:不是将部分路径(文件名)传递给组件,而是直接将导入的图像作为 属性 传递。图片会自动解析为Vite可以解析的绝对文件路径

这是一个例子:

<template>
  <Card :image="Teamwork" />
</template>

<script>
import Teamwork from '../../assets/teamwork.png';

export default {
  setup: () => {
    return { Teamwork };
  }
};
</script>

使用选项 API,您还可以通过 datacomputed 将图像传递给模板。使用 TypeScript,您还需要为图像定义垫片,以便您可以导入图像。