9

我将 Vue 3 与 Vite 一起使用。在 Vite 构建生产后,我遇到了动态 img src 的问题。对于静态 img src 没有问题。

<img src="/src/assets/images/my-image.png" alt="Image" class="logo"/>

它在两种情况下都运行良好:在开发模式下运行时以及在 vite 构建之后。但是我有一些图像名称存储在动态加载的数据库中(菜单图标)。在这种情况下,我必须像这样编写路径:

<img :src="'/src/assets/images/' + menuItem.iconSource" />

(menuItem.iconSource 包含图像的名称,如“my-image.png”)。在这种情况下,它在以开发模式运行应用程序时有效,但在生产构建后无效。当 Vite 为生产构建应用程序时,路径会更改(所有资产都放入_assets文件夹中)。静态图像源由 Vite 构建处理并相应更改路径,但组合图像源并非如此。它只是/src/assets/images/作为一个常量而不改变它(当应用程序抛出 404 not found for image /src/assets/images/my-image.png 时,我可以在网络监视器中看到它)。我试图找到解决方案,有人建议使用,require()但我不确定 vite 是否可以使用它。

4

4 回答 4

8

按照 Vite 文档,您可以使用此处提到和解释的解决方案:

文件

const imgUrl = new URL('./img.png', import.meta.url)

document.getElementById('hero-img').src = imgUrl

我在计算属性中使用它来动态设置路径,例如:

    var imagePath = computed(() => {
      switch (condition.value) {
        case 1:
          const imgUrl = new URL('../assets/1.jpg',
            import.meta.url)
          return imgUrl
          break;
        case 2:
          const imgUrl2 = new URL('../assets/2.jpg',
            import.meta.url)
          return imgUrl2
          break;
        case 3:
          const imgUrl3 = new URL('../assets/3.jpg',
            import.meta.url)
          return imgUrl3
          break;
      }
    });

非常适合我。

于 2021-07-27T10:39:47.357 回答
2

请尝试以下方法

const getSrc = (name) => {
    const path = `/static/icon/${name}.svg`;
    const modules = import.meta.globEager("/static/icon/*.svg");
    return modules[path].default;
  };
于 2021-06-17T02:13:27.557 回答
1

require()或者import()用于在基于 Webpack 的 Vue 应用程序中解决这种情况确实是 Webpack 唯一构造

在幕后,Webpack 处理此类动态导入,方法是使每个文件都位于/src/assets/images/应用程序包的路径 ( ) 部分的固定部分并可供导入。对于图像,这通常意味着创建某种内部地图,如下所示:

{
 'src/assets/images/image1.png' : 'assets/img/image1.hash.png',
  ...
}

关键是图像在源树中的路径。该值是由负责在构建期间处理图像的加载程序创建的路径(捆绑应用程序中的图像路径)。Webpack 在运行时使用此映射来“解析”动态生成的路径到图像的真实路径

在 Vite 中没有require(),但您可以通过使用Glob Import创建一个类似于上述的“地图”并自己使用此地图来做类似的事情

或者你可以使用这个插件以不太透明的方式做类似的事情......

此 GitHub 问题中的更多详细信息

更新

由于 Vite 在后台使用 Rollup,使用plugin-dynamic-import-vars可能是另一种解决方案,其用法与 Webpack 非常相似......

但是目前这有一个限制,即只允许相对路径,这使得 Glob Imports 可能是更好的选择

于 2021-03-01T10:27:55.010 回答
1

使用 Vite 的 APIimport.meta.glob效果很好,我参考了webpack-to-vite文档中的步骤。它列出了一些转换项和错误修复方法。它甚至可以一键将旧项目转换为 vite 项目。很棒,我推荐它!

  1. 创建一个模型来保存导入的模块,使用异步方法动态导入模块并将它们更新到模型中
// src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
const assets = import.meta.glob('../assets/**')
Vue.use(Vuex)
export default new Vuex.Store({
  state: {
    assets: {}
  },
  mutations: {
    setAssets(state, data) {
      state.assets = Object.assign({}, state.assets, data)
    }
  },
  actions: {
    async getAssets({ commit }, url) {
      const getAsset = assets[url]
      if (!getAsset) {
        commit('setAssets', { [url]: ''})
      } else {
        const asset = await getAsset()
        commit('setAssets', { [url]: asset.default })
      }
    }
  }
})
  1. .vue证监会中使用
// img1.vue
<template>
  <img :src="$store.state.assets['../assets/images/' + options.src]" />
</template>
<script>
export default {
  name: "img1",
  props: {
    options: Object
  },
  watch: {
    'options.src': {
      handler (val) {
        this.$store.dispatch('getAssets', `../assets/images/${val}`)
      },
      immediate: true,
      deep: true
    }
  }
}
</script>
于 2021-10-23T01:44:08.407 回答