Vue.jsの動的画像が機能しない


99

私は、私の場合持っているVue.jswebpackウェブアプリ、私はダイナミックな画像を表示する必要があります。img画像のファイル名が変数のどこに保存されているかを示したい。その変数は、に非同期で入力されているストア変数をcomputed返すプロパティです。VuexbeforeMount

<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
解決 :<SRC = "必要(V-IMG` @/assets/+ items.image)"高さ= "200pxの"> </ V-IMG>は`この1つはまた、問題を解決した
モハメド・ラザ

回答:


104

私は次のコードでこれを機能させました

  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
アントワーヌ

@Grigioこの回答への素敵な強化があります。stackoverflow.com/a/47480286/5948587
samlandfried

1
問題は、パスが存在しないことでした。vueアプリ全体がwebpackによって単一のスクリプトにコンパイルされます(画像も通常、コンテンツのハッシュを使用して名前が変更されます)。require.contextを使用して、ファイルを強制的にwebpackに表示させ、結果の画像に解決します。ブラウザの作業リンクを確認すると、私が何を意味するかがわかります。素晴らしいソリューション。
estani

画像をアセットフォルダに入れたくない場合はどうすればよいですか?管理エリアのユーザーによってアップロードされたために、Webサイトのパブリックフォルダーにのみ存在する場合はどうなりますか?
シンソルジャー

こんにちは、私はこれを試しましたが失敗しました、そして私はテンプレートリテラルを使用する別の解決策を見つけました。:それは仕事ができると私は、この共有したいstackoverflow.com/questions/57349167/...

86

これは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)
}

そして、ここの最初の2つの段落で、これが機能する理由を説明していることがわかりました上手。

ペットの写真を他のすべての画像アセットと一緒にロビー活動するのではなく、サブディレクトリ内に配置することをお勧めします。そのようです:./assets/pets/


`<v-img:src =" require(@/assets/+ items.image) "height =" 200px "> </ v-img>`これも問題を解決しました
MohamedRaza20年

これは、多くの試行を経た後の唯一の実用的な解決策でした。
makkus20年

45

require機能を試すことができます。このような:

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

なぜその@記号が必要なのですか?
危害を加える

1
@シンボルは必須ではありません。Resolve |srcを使用するときにディレクトリを表すことがよくあります。webpack(vue-cliはすでにこれを設定しています)。
fengzhang19年

21

画像ファイルをアセットではなくパブリックフォルダに追加し、静止画像としてアクセスする別の方法があります。

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

これは、静止画像を配置する必要がある場所です。

ここに画像の説明を入力してください


これは私がV-バインドを省略ALTタグを除き、私のために働いた
StefanBob

1
私に多くの痛みを保存し、私は奇妙なエラーを得た:モジュールが必要です「./undefined」を使用してを見つけることができません、ありがとう
ドラッカー

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/


本当に?正常
q2rzssxr

理由はわかりませんが、別の回答で書いたコードで動作しました。この関数がなくても動作する例があります。ここを参照してください:jsfiddle.net/9a6Lg2vd/1
Saurabh

私の場合、写真はVuexストアを使用して非同期で入力されています。これには何か関係がある可能性があります。シミュレートしようとしましたが、機能しませんでした:jsfiddle.net/9a6Lg2vd/2
Saurabh

私の場合はjsfiddle.net/9a6Lg2vd/4に似ていますが、私のローカルペットではajax呼び出しからデータが入力されますが、画像はレンダリングされません。
Saurabh 2016年

これも機能します:jsfiddle.net/9a6Lg2vd/5、ファイルパスで機能しない理由がわかりません。
Saurabh 2016年

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;
  }
}

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を使用してパスを解決する必要があります。次に、ブール変数と3項式を使用して画像を切り替えることができます。

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

そしてもちろん、いくつかのイベントハンドラーを介してブール値を切り替えます。


あなたに感謝この作品は:src="require(../assets/category_avatar/baby_kids.jpeg)"
モハメド・ラザ

2

Vue.jsはvue-loader、デプロイ(ローカル、開発、1つのホスティングプラットフォームまたはその他)間で異なる静的パスについて心配しないようにするために、コンパイル時にパスを書き換え/変換するように設定された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');
    }
}

私はこれについて自分で知りました。私に1時間かかりましたが...あなたは生きています、あなたは学びますよね?😊


0

私にとって最も簡単な方法は、APIからデータをフェッチする方法でした。

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

getPicメソッドは、ファイルの名前である1つのパラメーターを受け取り、ファイル名が単純なサーバーからのファイルの絶対パスを返します。

これは私がこれを使用したコンポーネントの例です:

<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">

0

ここですべての答えを試しましたが、Vue2で私のために働いたのはこのようなものです。

<div class="col-lg-2" v-for="pic in pics">
   <img :src="require(`../assets/${pic.imagePath}.png`)" :alt="pic.picName">
</div>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.