Hình ảnh động của Vue.js không hoạt động


90

Tôi có một trường hợp trong tôi Vue.jsvới webpackứng dụng web, tôi cần phải hiển thị hình ảnh động. Tôi muốn hiển thị imgnơi tên tệp của hình ảnh được lưu trữ trong một biến. Biến đó là một thuộc computedtính đang trả về một Vuexbiến cửa hàng, đang được điền không đồng bộ vào beforeMount.

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

Tuy nhiên, nó hoạt động hoàn hảo khi tôi chỉ làm:

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

Trường hợp của tôi tương tự với fiddle này , nhưng ở đây nó hoạt động với URL img, nhưng ở trường hợp của tôi với các đường dẫn tệp thực tế, nó không hoạt động.

Những gì nên được cách chính xác để làm điều đó?


1
đã giải quyết `<v-img: src =" @/assets/request ( + items.image) "height =" 200px "> </v-img>` cái này cũng giải quyết được vấn đề
Mohamed Raza

Câu trả lời:


98

Tôi đã làm việc này bằng cách làm theo mã

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

và trong HTML:

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

Nhưng không chắc tại sao cách tiếp cận trước đó của tôi không hoạt động.


7
Theo nickmaging: "Biểu thức bên trong v-bind được thực thi trong thời gian chạy, bí danh webpack tại thời điểm biên dịch." github.com/vuejs/vue-loader/issues/896
antoine

@Grigio có một cải tiến tốt cho câu trả lời này: stackoverflow.com/a/47480286/5948587
samlandfried

1
Vấn đề là đường dẫn không tồn tại. Toàn bộ ứng dụng vue được webpack biên dịch thành một tập lệnh duy nhất (và hình ảnh cũng được đổi tên bình thường bằng cách sử dụng hàm băm của nội dung). Sử dụng request.context, bạn buộc webpack nhìn thấy các tệp và phân giải thành hình ảnh kết quả. Kiểm tra liên kết làm việc trong trình duyệt và bạn sẽ thấy ý tôi. Giải pháp tuyệt vời.
estani

Điều gì xảy ra nếu tôi không muốn hình ảnh của mình nằm trong thư mục nội dung? Điều gì sẽ xảy ra nếu chúng chỉ tồn tại trong thư mục công cộng của trang web vì chúng được tải lên bởi người dùng của khu vực quản trị?
thinsoldier

xin chào, tôi đã thử điều này nhưng không thành công, sau đó tôi tìm thấy một giải pháp khác sử dụng các chữ mẫu. Nó có thể hoạt động và tôi muốn chia sẻ điều này: stackoverflow.com/questions/57349167/…
lin

82

Đây là cách viết tắt mà webpack sẽ sử dụng để bạn không cần phải sử dụng require.context.

HTML:

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

Phương pháp Vue:

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

Và tôi thấy rằng 2 đoạn đầu tiên trong đây giải thích tại sao điều này lại hiệu quả? tốt.

Xin lưu ý rằng bạn nên đặt ảnh thú cưng của bạn vào trong một thư mục con, thay vì đăng nhập nó với tất cả các nội dung hình ảnh khác của bạn. Như vậy:./assets/pets/


`<v-img: src =" @/assets/request ( + items.image) "height =" 200px "> </v-img>` cái này cũng giải quyết được vấn đề
Mohamed Raza

Đây là giải pháp hiệu quả duy nhất sau rất nhiều cố gắng ..
makkus

38

Bạn có thể thử requirechức năng. như thế này:

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

Tại sao phải có @ký hiệu đó ?
hại

1
@biểu tượng không bắt buộc, nó thường đại diện cho đồng tiền của bạn srckhi sử dụng Resolve | webpack (vue-cli đã cấu hình cái này.).
Feng zhang

20

Có một cách khác để làm điều đó bằng cách thêm các tệp hình ảnh của bạn vào thư mục chung thay vì nội dung và truy cập chúng dưới dạng hình ảnh tĩnh.

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

Đây là nơi bạn cần đặt các hình ảnh tĩnh của mình:

nhập mô tả hình ảnh ở đây


Điều này đã hiệu quả với tôi ngoại trừ thẻ alt mà tôi đã bỏ qua v-bind
StefanBob

1
đã cứu tôi rất nhiều đau đớn, tôi gặp lỗi lạ: Không thể tìm thấy mô-đun './undefined' bằng cách sử dụng request, cảm ơn
drakkar 18/02/19

1
Tôi nghĩ đây là cách để đi, không phải thư mục tài sản.
jukenduit

1
Yêu cầu động cũng không hoạt động đối với tôi trong Vue2 mới nhất
goodniceweb

8

Đặt cược tốt nhất của bạn là chỉ sử dụng một phương pháp đơn giản để tạo chuỗi chính xác cho hình ảnh tại chỉ mục đã cho:

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

sau đó làm như sau bên trong của bạn v-for:

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

Đây là JSFiddle (rõ ràng là các hình ảnh không hiển thị, vì vậy tôi đã đặt hình ảnh srcbên cạnh hình ảnh):

https://jsfiddle.net/q2rzssxr/


Có thật không? Dưới đây là một ví dụ với hình ảnh thực tế có vẻ hoạt động tốt: jsfiddle.net/q2rzssxr/1
craig_h

Không chắc tại sao, tôi đã làm cho nó hoạt động theo mã tôi đã viết trong một câu trả lời khác. Bạn ví dụ thậm chí làm việc không có chức năng này, xem tại đây: jsfiddle.net/9a6Lg2vd/1
Saurabh

Trong trường hợp của tôi, bức ảnh đã được dân cư không đồng bộ sử dụng Vuex cửa hàng, có thể là có một cái gì đó để làm gì về nó, tôi đã cố gắng để mô phỏng nó, nhưng đã không làm việc: jsfiddle.net/9a6Lg2vd/2
Saurabh

Trường hợp của tôi giống trường hợp này hơn: jsfiddle.net/9a6Lg2vd/4 , nhưng trong các vật nuôi địa phương của tôi nhận được dữ liệu từ một lệnh gọi ajax, nhưng hình ảnh không được hiển thị.
Saurabh

Điều này cũng hoạt động: jsfiddle.net/9a6Lg2vd/5 , không rõ tại sao nó không hoạt động với đường dẫn tệp.
Saurabh

5

Tôi cũng gặp sự cố này và có vẻ như cả hai câu trả lời được ủng hộ nhất đều hoạt động nhưng có một vấn đề nhỏ, webpack đưa ra một lỗi vào bảng điều khiển của trình duyệt (Lỗi: Không thể tìm thấy mô-đun './undefined' tại webpackContextResolve), điều này không được tốt cho lắm.

Vì vậy, tôi đã giải quyết nó hơi khác một chút. Toàn bộ vấn đề với biến bên trong câu lệnh request là câu lệnh request được thực thi trong quá trình gói và biến bên trong câu lệnh đó chỉ xuất hiện trong quá trình thực thi ứng dụng trong trình duyệt. Vì vậy, webpack xem hình ảnh bắt buộc là không xác định theo cả hai cách, vì trong quá trình biên dịch, biến đó không tồn tại.

Những gì tôi đã làm là đặt một hình ảnh ngẫu nhiên vào câu lệnh request và ẩn hình ảnh đó trong css, để không ai nhìn thấy nó.

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

Hình ảnh đến như một phần của thông tin từ cơ sở dữ liệu thông qua Vuex và được ánh xạ tới thành phần dưới dạng máy tính

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

Vì vậy, khi có thông tin này, tôi sẽ hoán đổi hình ảnh ban đầu thành hình ảnh thực

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

4

Đây là câu trả lời rất đơn giản. : D

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

3

Bạn có thể sử dụng khối try catch để giúp đỡ với những hình ảnh không tìm thấy

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

Đường dẫn tĩnh được Webpack giải quyết dưới dạng phụ thuộc mô-đun thông qua trình tải. Nhưng đối với đường dẫn động, bạn cần sử dụng request để giải quyết đường dẫn. Sau đó, bạn có thể chuyển đổi giữa các hình ảnh bằng cách sử dụng biến boolean & biểu thức bậc ba.

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

Và tất nhiên chuyển đổi giá trị của boolean thông qua một số trình xử lý sự kiện.


Cảm ơn bạn tác phẩm này :src="require(../assets/category_avatar/baby_kids.jpeg)"
Mohamed Raza

0

cách tốt nhất và dễ nhất phù hợp với tôi là cách này mà tôi đang tìm nạp dữ liệu từ một API ..

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

phương thức getPic nhận một tham số là tên của tệp và nó trả về đường dẫn tuyệt đối của tệp có thể từ máy chủ của bạn với tên tệp đơn giản ...

đây là một ví dụ về một thành phần mà tôi đã sử dụng:

<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

Tôi gặp phải vấn đề tương tự. Điều này đã hiệu quả với tôi bằng cách thay đổi '../assets/' thành './assets/'.

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

-1

Hãy thử nhập hình ảnh như thế này, vì Webpack nên biết về mức độ phụ thuộc của nó

    <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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.