Vue.js动态图像不起作用

时间:2016-11-08 16:07:21

标签: javascript html vue.js vuejs2

我有一个案例,在我的Vue.jswebpack网络应用中,我需要显示动态图片。我想显示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">

我的情况与此fiddle类似,但此处它适用于img网址,但在我的实际文件路径中,它不起作用。

应该采用哪种方法?

15 个答案:

答案 0 :(得分:48)

我按照代码

开始工作
  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>

但不确定为什么我之前的方法不起作用。

答案 1 :(得分:23)

以下是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)
}

我发现Attach the failing disk中的前两段解释 为什么会这样?

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

答案 2 :(得分: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/

答案 3 :(得分:7)

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

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

答案 4 :(得分:6)

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

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

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

enter image description here

答案 5 :(得分:6)

我也遇到了这个问题,似乎两个最支持的答案都起作用,但是有一个小问题,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;
  }
}

答案 6 :(得分:2)

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

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

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

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

答案 7 :(得分:1)

我正在使用这种模式,并且效果很好。

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

答案 8 :(得分:1)

您可以使用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
},

答案 9 :(得分:1)

Vue.js使用vue-loader,这是WebPack的加载器,其设置为在编译时重写/转换路径,以使您不必担心静态路径在部署之间会有所不同(本地,开发,一个托管平台或另一个托管平台),方法是允许您使用相对本地文件系统路径。它还增加了资产缓存和版本控制等其他好处(您可以通过检查实际生成的src URL来看到这一点。)

因此,将通常由vue-loader / WebPack处理的src设置为动态表达式,并在运行时对其进行评估,将绕过此机制,并且在实际部署的上下文中,生成的动态URL将无效(除非它是完全合格的,否则是例外)。

如果相反,您将在动态表达式中使用require函数调用,vue-loader / WebPack将看到它并应用通常的魔术。

例如,这行不通:

<img alt="Logo" :src="logo" />
computed: {
    logo() {
        return this.colorMode === 'dark'
               ? './assets/logo-dark.png'
               : './assets/logo-white.png';
    }
}

这可行:

<img alt="Logo" :src="logo" />
computed: {
    logo() {
        return this.colorMode === 'dark'
               ? require('./assets/logo-dark.png')
               : require('./assets/logo-white.png');
    }
}

我自己才发现这一点。花了我一个小时,但是...你住了,学到了,对吗? ?

答案 10 :(得分:1)

当我使用 Gridsome 时,这种方式对我有用。

**我也用过 toLowerCase() 方法

app.listen

答案 11 :(得分: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>

答案 12 :(得分:0)

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

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

答案 13 :(得分:0)

在这里尝试了所有答案,但是在Vue2上对我有用的就是这样。

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

答案 14 :(得分:-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>