Vue.js गतिशील छवियां काम नहीं कर रही हैं


100

मेरे पास एक ऐसा मामला है जहां मेरे वेब ऐप के 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 =" आवश्यकता ( @/assets/+ आइटम.समाज) "ऊँचाई =" 200px "> </ v-img>` यह भी समस्या हल
मोहम्मद रज़ा

जवाबों:


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
निकम्सिंग के अनुसार: "वी-बिंद के अंदर की अभिव्यक्ति को रनटाइम पर निष्पादित किया जाता है, संकलन समय पर वेबपैक उपनाम।" github.com/vuejs/vue-loader/issues/896
antoine

@Grigio के पास इस उत्तर की अच्छी वृद्धि है: stackoverflow.com/a/47480286/5948587
samlandfried

1
समस्या यह थी कि रास्ता मौजूद नहीं है। पूरे vue ऐप को वेबपैक द्वारा एक ही स्क्रिप्ट में संकलित किया जाता है (और सामग्री के हैश का उपयोग करके छवियों को भी सामान्य रूप से बदल दिया जाता है)। आवश्यकता का उपयोग करके। संदर्भ के लिए, आप वेबपैक द्वारा देखी जाने वाली फ़ाइलों को बाध्य करते हैं और परिणामी छवि को हल करते हैं। ब्राउज़र में काम कर रहे लिंक की जाँच करें और आप देखेंगे कि मेरा क्या मतलब है। महान समाधान।
एस्टानी

क्या होगा यदि मैं नहीं चाहता कि मेरी छवियां संपत्ति फ़ोल्डर में हों? क्या होगा यदि वे केवल वेबसाइट के सार्वजनिक फ़ोल्डर में मौजूद हैं क्योंकि वे व्यवस्थापक क्षेत्र के उपयोगकर्ताओं द्वारा अपलोड किए गए हैं?
thinsoldier

हैलो, मैंने यह कोशिश की है, लेकिन असफल रहा, तो मुझे एक और समाधान मिला कि टेम्पलेट शाब्दिक का उपयोग करना। यह काम कर सकता है और मैं इसे साझा करना चाहता हूं: stackoverflow.com/questions/57349167/…
lin

87

यहाँ एक शॉर्टहैंड है जो वेबपैक उपयोग करेगा ताकि आपको उपयोग न करना पड़े 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 =" आवश्यकता ( @/assets/+ आइटम.समाज) "ऊँचाई =" 200px "> </ v-img>` यह भी समस्या हल
मोहम्मद रज़ा

बहुत कोशिश के बाद यह एकमात्र काम करने वाला उपाय था ..
makkus

45

आप requireफ़ंक्शन को आज़मा सकते हैं । इस तरह:

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

उस @प्रतीक की आवश्यकता क्यों है ?
नुकसान

1
@प्रतीक की आवश्यकता नहीं है, यह आपके प्रतिनिधित्व offten srcका उपयोग करते समय dir हल | webpack (vue-cli यह पहले से ही कॉन्फ़िगर है।)।
फेंग झांग

21

संपत्ति के बजाय सार्वजनिक फ़ोल्डर में अपनी छवि फ़ाइलों को जोड़कर ऐसा करने का एक और तरीका है और उन्हें स्थिर छवियों के रूप में एक्सेस करना है।

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

यह वह जगह है जहां आपको अपनी स्थिर छवियां डालने की आवश्यकता है:

यहाँ छवि विवरण दर्ज करें


इसने मेरे लिए काम किया सिवाय उस टैग के, जिसे मैंने वी-बाइंड छोड़ा था
स्टीफनबेक

1
मुझे दर्द का एक बहुत कुछ बचा लिया, मैं अजीब त्रुटि मिल गया: मॉड्यूल './undefined' का उपयोग की आवश्यकता नहीं मिल सकता है, धन्यवाद
drakkar

1
मुझे लगता है कि यह जाने का तरीका है, न कि संपत्ति फ़ोल्डर।
जुकेंडिट

1
डायनामिक आवश्यकता मेरे लिए नवीनतम V22
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
सौरभ

मेरे मामले में, तस्वीरें एसिंक्रोनस रूप से डाला जा रहा है Vuex दुकान का उपयोग कर, कि इसके बारे में क्या करने के लिए कुछ न कुछ है हो सकता है, मैं इसे अनुकरण करने के लिए कोशिश की, लेकिन काम नहीं किया: jsfiddle.net/9a6Lg2vd/2
सौरभ

मेरे मामले अधिक इस तरह है: jsfiddle.net/9a6Lg2vd/4 , लेकिन मेरे स्थानीय पालतू जानवर में एक ajax कॉल से आबादी वाले डेटा हो जाता है, लेकिन छवियों प्रस्तुत करना नहीं मिलता।
सौरभ 3

यह भी काम करता है: jsfiddle.net/9a6Lg2vd/5 , यह सुनिश्चित नहीं है कि यह फ़ाइल पथों के साथ काम क्यों नहीं कर रहा है।
सौरभ

6

मैंने इस समस्या को भी मारा और ऐसा लगता है कि दोनों सबसे उत्कीर्ण उत्तर काम करते हैं, लेकिन एक छोटी सी समस्या है, वेबपैक ब्राउज़र कंसोल (त्रुटि: त्रुटि का पता नहीं लगा सकता है।

इसलिए मैंने इसे थोड़ा अलग तरीके से हल किया है। स्टेटमेंट के अंदर वैरिएबल के साथ पूरी समस्या यह है कि बंडलिंग के दौरान स्टेटमेंट की आवश्यकता होती है और उस स्टेटमेंट के अंदर वैरिएबल केवल ब्राउज़र में ऐप निष्पादन के दौरान दिखाई देता है। इसलिए वेबपैक आवश्यक छवि को किसी भी तरह अपरिभाषित देखता है, जैसे संकलन के दौरान कि चर मौजूद नहीं है।

मैंने जो किया वह रैंडम इमेज को स्टेटमेंट में डालने और उस इमेज को 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

तुम नहीं छवियों के साथ मदद करने के लिए पकड़ने के ब्लॉक का उपयोग कर सकते हैं

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

स्थिर पथ को लोडर के माध्यम से वेबपैक द्वारा मॉड्यूल निर्भरता के रूप में हल किया जाता है। लेकिन गतिशील पथ के लिए आपको पथ को हल करने के लिए उपयोग करने की आवश्यकता होती है। फिर आप बूलियन वैरिएबल और टर्नरी एक्सप्रेशन का उपयोग करके छवियों के बीच स्विच कर सकते हैं।

<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, WebPack के लिए एक लोडर जो संकलन समय पर पथों को फिर से लिखने / परिवर्तित करने के लिए सेट है, ताकि आप स्थैतिक रास्तों के बारे में चिंता न कर सकें जो कि तैनाती के बीच भिन्न होंगे (स्थानीय, देव, एक होस्टिंग या अन्य) , आप रिश्तेदार स्थानीय फाइल सिस्टम पथ का उपयोग करने की अनुमति देकर । यह एसेट कैशिंग और वर्जनिंग जैसे अन्य लाभों को भी जोड़ता है (आप इसे वास्तविक srcURL उत्पन्न होने की जाँच करके देख सकते हैं )।

इसलिए एक src होने जो सामान्य रूप से vue-loader/ WebPack द्वारा एक गतिशील अभिव्यक्ति के लिए संभाला जाता है , रनटाइम पर मूल्यांकन किया जाता है, इस तंत्र को दरकिनार करेगा और उत्पन्न गतिशील 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');
    }
}

मुझे अभी खुद इस बारे में पता चला है। मुझे एक घंटा लगा लेकिन ... आप रहते हैं, आप सीखते हैं, है ना? 😊


0

मेरे लिए काम करने का सबसे अच्छा और आसान तरीका यही था जिसमें मैं एक एपीआई से डेटा प्राप्त कर रहा था।

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

0

यहाँ सभी जवाबों की कोशिश की लेकिन Vue2 पर मेरे लिए जो काम किया वह इस तरह है।

<div class="col-lg-2" v-for="pic in pics">
   <img :src="require(`../assets/${pic.imagePath}.png`)" :alt="pic.picName">
</div>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.