如何在vue javascript中引用静态资源

171

我正在寻找正确的URL来引用静态资源,比如在Vue JavaScript内的图像。

例如,我正在创建一个使用自定义图标图像的leaflet标记,并且我尝试了几个URL,但它们都返回404(未找到)

Main.vue:

var icon = L.icon({
    iconUrl: './assets/img.png',
    iconSize:     [25, 25],
    iconAnchor:   [12, 12]
});

我尝试将图片放在assets文件夹和static文件夹中,但都没成功。我需要告诉Vue如何加载这些图片吗?


webpack?通常需要知道是否包含图像,以便将其放入捆绑包中。其他捆绑系统可能不关心,只要图像部署到您的服务器即可。 - akatakritos
14个回答

266

如果有人想要从模板中引用图片,可以直接使用“@”来引用图片。

例如:

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

2
假设你有一个名为src/assets/images的文件夹。vue-loader默认会将src/../..中的资源复制到build/../..,或者自动将较小的图片作为data.image/png内联。 - user783388
21
对我没有用:“未找到此依赖项:*@/assets/more-ico.svg。您可以运行npm install --save @/assets/more-ico.svg来安装它。” - Jakub Strebeyko
3
对我也没用,但是……然后我发现我使用了错误的文件名;p,现在完美运行! - Larzan
10
它能正常运行,但是如果你想在 css 的 background-img 属性中使用它,尝试像这样使用 ../../assets/bg/login.svg,并将图片放入 assets 文件夹中。 - calebeaires
9
谢谢。Vue文档中有关静态资源的说明过于详细,而且将这一主要用例几乎埋在页面底部的一个小圆点中。请问需要翻译哪种语言? - Our_Benefactors
显示剩余6条评论

113
在Vue的常规设置中,/assets不会被提供。图片将变为src="data:image/png;base64,iVBORw0K...YII="字符串。
在JavaScript内使用require():要从JS代码获取图片,请使用require('../assets.myImage.png')。 路径必须是相对路径(见下文)。
因此,您的代码将是:
var icon = L.icon({
    iconUrl: require('./assets/img.png'),   // was iconUrl: './assets/img.png',
//  iconUrl: require('@/assets/img.png'), // use @ as alternative, depending on the path
    // ...
});

使用相对路径

例如,假设您有以下文件夹结构:

- src
  +- assets
     - myImage.png
  +- components
     - MyComponent.vue

如果您想引用MyComponent.vue中的图像,路径应为../assets/myImage.png


以下是演示CODESANDBOX,展示其工作原理。


2
使用vue-cli搭建我的应用程序后,这种技术对我很有帮助。Code Sandbox非常有帮助。答案没有代码沙盒那么清晰。 - revdrjrr
在我的组件选项中,require('./assets/img.png') 对我不起作用,我不得不将.替换为@require('@/assets/img.png') - Hans

44

更好的解决方案是

在@acdcjunior的答案上加入一些良好的实践和安全措施,使用@而不是./

在JavaScript中

require("@/assets/images/user-img-placeholder.png")

在JSX模板中

<img src="@/assets/images/user-img-placeholder.png"/>

使用 @ 指向 src 目录。

使用 ~ 指向项目根目录,这样可以更轻松地访问 node_modules 和其他根级资源。


如果不是图像而是文本文件或CSV文件呢?只想获取路径/ URL怎么办? - trainoasis
@trainoasis,您可以使用<a href="...">标签来上传其他类型的文件。 - MYriad

26
为了使Webpack返回正确的资源路径,您需要使用require('./relative/path/to/file.jpg'),这将被file-loader处理并返回已解析的URL。
computed: {
  iconUrl () {
    return require('./assets/img.png')
    // The path could be '../assets/img.png', etc., which depends on where your vue file is
  }
}

查看 VueJS 模板 - 处理静态资源


18
在打开脚本标签后,只需添加 import someImage from '../assets/someImage.png' 并将其用于图标 URL iconUrl: someImage

2
当我在导入中加入“@”符号时,这对我非常有效。 - vab2048
动态图片怎么样? - Fernando Torres

17

这对我最终奏效了,图像作为属性传递:

<img :src="require(`../../assets/${image}.svg`)">

6
或者使用"@": <img :src="require(`@/assets/${image}.svg`)"> - Raine Revere
在我的情况下,我使用了 require(../assets/country-flags-main/...svg)。 - Fernando Torres

2

您使用的是什么系统?Webpack?Vue-loader?

我只是在这里进行头脑风暴...

因为.png不是JavaScript文件,所以您需要配置Webpack使用file-loader或url-loader来处理它们。使用vue-cli搭建的项目已经为您配置了此项功能。

您可以查看webpack.conf.js以确定是否已正确配置。

...
    {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
...

/assets 文件夹中的文件由 webpack 在打包过程中处理 - 因此,它们必须在你的 JavaScript 代码中被引用。

其他资源可以放在 /static 文件夹中,该文件夹中的内容将作为原样复制到 /dist 中。

我建议您尝试更改:

iconUrl: './assets/img.png'

为:

iconUrl: './dist/img.png'

您可以在这里阅读官方文档:https://vue-loader.vuejs.org/en/configurations/asset-url.html

希望对您有所帮助!


我不确定我正在使用什么系统,或者是否需要手动添加。我尝试了./dist URL,但没有成功。 - JBaczuk

1

我使用如下的require语法,它对我有效:

$('.eventSlick').slick({
    dots: true,
    slidesToShow: 3,
    slidesToScroll: 1,
    autoplay: false,
    autoplaySpeed: 2000,
    arrows: true,
    draggable: false,
    prevArrow: '<button type="button" data-role="none" class="slick-prev"><img src="' + require("@/assets/img/icon/Arrow_Left.svg")+'"></button>',

1

您可以根据您的环境定义资产路径

const dev = process.env.NODE_ENV != 'production';
const url = 'https://your-site.com';
const assets = dev ? '' : url;

<template>
    <img :src="`${assets}/logo.png`"/>
    <p>path: {{assets}}</p>
</template>
<script>
    export default {
        data: () => ({
            assets
        })
    }
</script>

理想情况下,这应该在一个 utils js 文件中,或者作为扩展的 app defineProperty,例如:
const app = createApp(component);
app.config.globalProperties.$assets = assets;
app.mount(element);

并将作为可用选项:

<template>
    <img :src="`${$assets}/logo.png`"/>
    <p>path: {{$assets}}</p>
</template>
<script>
    export default {
        mounted() {
            console.log(this.$assets);
        }
    }
</script>

0

将它们加载到创建的、挂载的或需要它们的位置

async created() {
   try {
      this.icon = (await import('@assets/images/img.png')).default;
   } catch (e) {
      // explicitly ignored
   }

然后

<img :src=icon />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接