Vue.js动态图像无法正常工作


90

我有一种情况,在Vue.js使用webpack网络应用程序时,我需要显示动态图像。我想显示img图像文件名存储在变量中的位置。该变量是一个computed属性,它返回一个Vuex存储变量,该变量在上异步填充beforeMount

<div class="col-lg-2" v-for="pic in pics">
   <img v-bind:src="'../assets/' + pic + '.png'" v-bind:alt="pic">
</div>

但是,当我刚做的时候它完美地工作:

<img src="../assets/dog.png" alt="dog">

我的情况与此小提琴类似,但是在这里它适用于img URL,但是在我的具有实际文件路径的情况下,它不起作用。

正确的方法是什么?


1
解决了 <v-img:src =“ require(@/assets/+ items.image)” height =“ 200px”> </ v-img>`这也解决了问题
Mohamed Raza

Answers:


98

我通过以下代码来工作

  getImgUrl(pet) {
    var images = require.context('../assets/', false, /\.png$/)
    return images('./' + pet + ".png")
  }

并在HTML中:

<div class="col-lg-2" v-for="pic in pics">
   <img :src="getImgUrl(pic)" v-bind:alt="pic">
</div>

但不确定为什么我的早期方法不起作用。


7
据昵称:“ v-bind内的表达式在运行时执行,webpack别名在编译时执行。” github.com/vuejs/vue-loader/issues/896
antoine

@Grigio对这个答案有一个很好的增强:stackoverflow.com/a/47480286/5948587
samlandfried

1
问题在于该路径不存在。整个vue应用程序都由webpack编译成一个脚本(图像也使用内容的哈希值正常重命名)。使用require.context,可以强制文件被webpack看到并解析为生成的图像。在浏览器中检查工作链接,您将明白我的意思。很好的解决方案。
estani

如果我不想将图像放在资产文件夹中怎么办?如果由于管理员区域的用户上载而仅存在于网站的公用文件夹中,该怎么办?
Thinsoldier

你好,我尝试过但是失败了,然后我找到了另一个使用模板文字的解决方案。它可以工作,我想分享这个:stackoverflow.com/questions/57349167/...

82

这是webpack将使用的一种速记方式,因此您不必使用require.context

HTML:

<div class="col-lg-2" v-for="pic in pics">
    <img :src="getImgUrl(pic)" v-bind:alt="pic">
</div>

Vue方法:

getImgUrl(pic) {
    return require('../assets/'+pic)
}

而且我发现这里的前两段解释了为什么这样做?好。

请注意,将宠物图片放置在子目录中是一个好主意,而不是将其与其他所有图片资源一起放入。像这样:./assets/pets/


`<v-img:src =“ require(@/assets/+ items.image)” height =“ 200px”> </ v-img>`这个也解决了问题
Mohamed Raza

这是一个很多的努力..后唯一的工作解决
makkus

38

您可以尝试该require功能。像这样:

<img :src="require(`@/xxx/${name}.png`)" alt class="icon" />

为什么@需要该符号?
损害

1
@符号不是必需的,src使用Resolve |时它可以代表您的目录 webpack(已经配置了vue-cli。)。
张锋

20

还有另一种方法,可以将图像文件添加到公用文件夹而不是资产中,然后将其作为静态图像访问。

<img :src="'/img/' + pic + '.png'" v-bind:alt="pic" >

这是您需要放置静态图像的地方:

在此处输入图片说明


这对我
有用,

1
为我节省了很多痛苦,我感到很奇怪错误:无法使用require找到模块“ ./undefined”,谢谢
drakkar

1
我认为这是要走的路,而不是资产文件夹。
jukenduit

1
动态需求在最新的Vue2中也对我不起作用
goodniceweb

8

最好的选择是仅使用一种简单的方法为给定索引的图像构建正确的字符串:

methods: {
  getPic(index) {
    return '../assets/' + this.pics[index] + '.png';
  }
}

然后在您的内部执行以下操作v-for

<div class="col-lg-2" v-for="(pic, index) in pics">
   <img :src="getPic(index)" v-bind:alt="pic">
</div>

这是JSFiddle(显然图像未显示,因此我将图像放在图像src旁边):

https://jsfiddle.net/q2rzssxr/


真?这是一个看起来不错的真实图像示例:jsfiddle.net/q2rzssxr/1
craig_h 2016年

不知道为什么,我在另一个答案中编写的代码使它起作用。您的示例甚至可以在没有此功能的情况下工作,请参见此处:jsfiddle.net/9a6Lg2vd/1
Saurabh

就我而言,图片是使用Vuex商店异步填充的,可能与它有关,我尝试对其进行仿真,但无法正常工作:jsfiddle.net/9a6Lg2vd/2
Saurabh

我的情况更像这样:jsfiddle.net/9a6Lg2vd/4,但是在我的本地宠物中,通过ajax调用填充了数据,但是没有渲染图像。
萨拉巴

这也适用:jsfiddle.net/9a6Lg2vd/5,不确定为什么它不能使用文件路径。
萨拉巴

5

我也遇到了这个问题,似乎两个建议最多的答案都可以,但是有一个小问题,webpack向浏览器控制台抛出错误(错误:在webpackContextResolve中找不到模块'./undefined'),这不是很好。

所以我已经解决了一些不同的问题。require语句内的变量的整个问题是,require语句在绑定期间执行,而该语句内的变量仅在浏览器中的应用执行期间出现。因此,webpack会将所需的映像视为未定义的映像,因为在编译期间该变量不存在。

我所做的是将随机图像放入require语句中并将该图像隐藏在CSS中,因此没人看到它。

// template
<img class="user-image-svg" :class="[this.hidden? 'hidden' : '']" :src="userAvatar" alt />

//js
data() {
  return {
    userAvatar: require('@/assets/avatar1.svg'),
    hidden: true
  }
}

//css
.hidden {display: none}

图像作为信息的一部分通过Vuex来自数据库,并作为计算对象映射到组件

computed: {
  user() {
    return this.$store.state.auth.user;
  }
}

因此,一旦获得此信息,我便会将初始图像交换为真实图像

watch: {
  user(userData) {
    this.userAvatar = require(`@/assets/${userData.avatar}`);
    this.hidden = false;
  }
}

4

这是非常简单的答案。:D

<div class="col-lg-2" v-for="pic in pics">
   <img :src="`../assets/${pic}.png`" :alt="pic">
</div>

3

您可以使用try catch块来帮助查找未找到的图像

getProductImage(id) {
          var images = require.context('@/assets/', false, /\.jpg$/)
          let productImage = ''
          try {
            productImage = images(`./product${id}.jpg`)
          } catch (error) {
            productImage = images(`./no_image.jpg`)
          }
          return productImage
},

2
<img src="../assets/graph_selected.svg"/>

Webpack通过加载程序将静态路径解析为模块依赖项。但是对于动态路径,您需要使用require来解析路径。然后,您可以使用布尔变量和三元表达式在图像之间切换。

<img :src="this.graph ? require( `../assets/graph_selected.svg`) 
: require( `../assets/graph_unselected.svg`) " alt="">

当然,可以通过一些事件处理程序来切换布尔值。


谢谢你的工作:src="require(../assets/category_avatar/baby_kids.jpeg)"
穆罕默德·拉扎

0

对我来说,最好,最简单的方法就是从API提取数据。

methods: {
       getPic(index) {
    return this.data_response.user_Image_path + index;
  }
 }

getPic方法采用一个参数即文件名,它可以从服务器返回文件的绝对路径,其文件名简单...

这是我使用此组件的示例:

<template>
    <div class="view-post">
        <div class="container">
     <div class="form-group">
             <label for=""></label>
             <input type="text" class="form-control" name="" id="" aria-describedby="helpId" placeholder="search here">
             <small id="helpId" class="form-text user-search text-muted">search for a user here</small>
           </div>
           <table class="table table-striped ">
               <thead>
                   <tr>
                       <th>name</th>
                       <th>email</th>
                       <th>age</th>
                       <th>photo</th>
                   </tr>
                   </thead>
                   <tbody>
                       <tr v-bind:key="user_data_get.id"  v-for="user_data_get in data_response.data">
                           <td scope="row">{{ user_data_get.username }}</td>
                           <td>{{ user_data_get.email }}</td>
                           <td>{{ user_data_get.userage }}</td>
                           <td><img :src="getPic(user_data_get.image)"  clas="img_resize" style="height:50px;width:50px;"/></td>
                       </tr>

                   </tbody>
           </table>
        </div>

    </div>
</template>

<script>
import axios from 'axios';
export default {
     name: 'view',
  components: {

  },
  props:["url"],
 data() {
     return {
         data_response:"",
         image_path:"",
     }
 },
 methods: {
       getPic(index) {
    return this.data_response.user_Image_path + index;
  }
 },
 created() {
     const res_data = axios({
    method: 'post',
    url: this.url.link+"/view",
   headers:{
     'Authorization': this.url.headers.Authorization,
     'content-type':this.url.headers.type,
   }
    })
    .then((response)=> {
        //handle success
      this.data_response = response.data;
      this.image_path = this.data_response.user_Image_path;
       console.log(this.data_response.data)
    })
    .catch(function (response) {
        //handle error
        console.log(response);
    });
 },
}
</script>


<style scoped>

</style>

0

我遇到了同样的问题。这通过将'../assets/'更改为'./assets/'对我有用。

 <img v-bind:src="'./assets/' + pic + '.png'" v-bind:alt="pic">

-1

尝试像这样导入图像,因为Webpack应该知道其依赖关系

    <ul>
              <li v-for="social in socials" 
              v-bind:key="social.socialId"
              >

                <a :href="social.socialWeb" target="_blank">
                  <img class="img-fill" :id="social.socialId" :src="social.socialLink" :alt="social.socialName">
                </a>
              </li>

            </ul>

<script>
        import Image1 from '@/assets/images/social/twitter.svg'
        import Image2 from '@/assets/images/social/facebook.svg'
        import Image3 from '@/assets/images/social/rss.svg'
        export default {
          data(){
            return{
              socials:[{         
                   socialId:1,         
                   socialName: "twitter",
                   socialLink: Image1,
                   socialWeb: "http://twitter.com"
              },
      {
          socialId:2,
          socialName: "facebook",
           socialLink: Image2,
           socialWeb: "http://facebook.com"

      },
      {
          socialId:3,
          socialName: "rss",
           socialLink: Image3,
           socialWeb: "http://rss.com"
      }]

 </script>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.