Vue.js 동적 이미지가 작동하지 않음


90

내 한 경우이 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
해결 `<v-img : src = "require ( @/assets/+ items.image)"height = "200px"> </ v-img>`이것도 문제를 해결했습니다
Mohamed Raza

답변:


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
nickmessing에 따르면 : "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/…
lin

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
@기호가 필요하지 않습니다, 그것은 당신의 표현 offten src사용하는 경우 디렉토리를 해결을 | webpack (vue-cli는 이미 구성되어 있습니다.).
feng zhang

20

자산 대신 공용 폴더에 이미지 파일을 추가하고 정적 이미지로 액세스하는 또 다른 방법이 있습니다.

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

여기에 정적 이미지를 넣어야합니다.

여기에 이미지 설명 입력


이것은 내가 v-bind를 생략 한 alt 태그를 제외하고는 나를 위해 일했습니다
StefanBob

1
나에게 많은 고통을 저장, 나는 이상한 오류가 발생했습니다 : 모듈이 필요합니다 './undefined'사용을 찾을 수 없습니다, 감사
drakkar

1
자산 폴더가 아니라 이것이 갈 길이라고 생각합니다.
jukenduit

1
dynamic require가 최신 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

왜 그런지 모르겠지만 다른 답변으로 작성한 코드로 작동합니다. 이 함수 없이도 작동하는 예제입니다. 여기를 참조하십시오. jsfiddle.net/9a6Lg2vd/1
Saurabh

제 경우에는 사진이 Vuex 저장소를 사용하여 비동기식으로 채워지고 있습니다. 관련 작업이있을 수 있습니다. 시뮬레이션을 시도했지만 작동하지 않았습니다. jsfiddle.net/9a6Lg2vd/2
Saurabh

내 경우는 jsfiddle.net/9a6Lg2vd/4 와 비슷하지만 내 지역 애완 동물에서는 ajax 호출에서 데이터가 채워지지만 이미지가 렌더링되지 않습니다.
Saurabh

이것은 또한 작동합니다 : jsfiddle.net/9a6Lg2vd/5 , 왜 파일 경로와 함께 작동하지 않는지 확실하지 않습니다.
Saurabh

5

나는 또한이 문제에 부딪 혔고 대부분의 upvoted 답변이 작동하지만 작은 문제가있는 것 같습니다 .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

여기 아주 간단한 대답이 있습니다. :디

<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)"
Mohamed Raza

0

저에게 가장 좋고 가장 쉬운 방법은 API에서 데이터를 가져 오는 것이 었습니다.

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

getPic 메소드는 파일 이름 인 하나의 매개 변수를 취하고 파일 이름이 simple 인 서버에서 파일의 절대 경로를 반환합니다.

다음은 이것을 사용한 구성 요소의 예입니다.

<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>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.