[英]Vue.js dynamic images not working
我有一個案例,在我的Vue.js
和webpack
web 應用程序中,我需要顯示動態圖像。 我想顯示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,但在我的實際文件路徑中,它不起作用。
正確的做法應該是什么?
我通過以下代碼得到了這個工作
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>
但不知道為什么我之前的方法不起作用。
這是 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/ ./assets/pets/
你可以試試require
函數。 像這樣:
<img :src="require(`@/xxx/${name}.png`)" alt class="icon" />
@
符號指向src
目錄。
來源: Vue URL 轉換規則
最好的辦法是使用一種簡單的方法在給定索引處為圖像構建正確的字符串:
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
放在圖像旁邊):
我也遇到了這個問題,似乎兩個最受好評的答案都有效,但有一個小問題,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;
}
}
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');
}
}
我自己才發現這件事。 花了我一個小時,但是……你活着,你學習,對吧? 😊
<img src="../assets/graph_selected.svg"/>
靜態路徑由 Webpack 通過 loader 解析為模塊依賴。 但是對於動態路徑,您需要使用 require 來解析路徑。 然后,您可以使用布爾變量和三元表達式在圖像之間切換。
<img :src="this.graph ? require( `../assets/graph_selected.svg`)
: require( `../assets/graph_unselected.svg`) " alt="">
當然,通過一些事件處理程序來切換布爾值。
<div
v-for="(data, i) in statistics"
:key="i"
class="d-flex align-items-center"
>
<img :src="require('@/assets/images/'+ data.title + '.svg')" />
<div class="ml-2 flex-column d-flex">
<h4 class="text-left mb-0">{{ data.count }}</h4>
<small class="text-muted text-left mt-0">{{ data.title }}</small>
</div>
</div>
這是非常簡單的答案。 :D
<div class="col-lg-2" v-for="pic in pics">
<img :src="`../assets/${pic}.png`" :alt="pic">
</div>
您可以使用 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
},
在這里嘗試了所有答案,但在 Vue2 上對我有用的是這樣。
<div class="col-lg-2" v-for="pic in pics">
<img :src="require(`../assets/${pic.imagePath}.png`)" :alt="pic.picName">
</div>
當我使用 Gridsome 時,這種方式對我有用。
**我也用過 toLowerCase() 方法
<img
:src="
require(`@/assets/images/flags/${tournamentData.address.country_name.toLowerCase()}.svg`)
"
/>
我也遇到過這個問題。
試試看:
computed {
getImage () {
return require(`../assets/images/${imageName}.jpg`) // the module request
}
}
這是一篇很好的文章,澄清了這一點: https ://blog.lichter.io/posts/dynamic-images-vue-nuxt/
對我來說最好和最簡單的方法就是我從 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>
我遇到了同樣的問題。 通過將“../assets/”更改為“./assets/”,這對我有用。
<img v-bind:src="'./assets/' + pic + '.png'" v-bind:alt="pic">
到今天為止,使用VUE 3 + Typescript & composition AP I,我所做的是在 try catch 中包裝 require 函數來處理崩潰。
computed: {
getImage() {
let imgSrc = "";
try {
imgSrc = require(`../assets/weather-widget-icons/ww-icon-${this.weatherForecast.main.toLowerCase()}.svg`);
} catch (error) {
console.error(`Image '../assets/weather-widget-icons/ww-icon-${this.weatherForecast.main.toLowerCase()}.svg' not found!`);
}
return imgSrc;
}
}
並在圖像標簽中調用此函數:
<div class="weather-icon">
<img :src="getImage" :alt="weatherForecast.main" />
</div>
圖像需要轉錄。 對我有用的是將圖像放在公共文件夾中。 即公共/資產/img
Dynamic Image Tag:
<div v-for="datum in data">
<img
class="package_image"
style="max-width:200px;"
alt="Vue logo"
:src="`./assets/img/${datum.image}`"
>
<div>
我有一個您可能想嘗試的解決方案。
定義如下方法
methods: {
getFlagImage(flag){
return new URL('/resources/img/flags/'+flag+'.png', import.meta.url);
},
}
然后可以使用已建立的 for 循環調用圖像
<li :class=" 'nav-item', {'active': language === key} " v-for="(value,
key) in locals" :key="value ">
<a class="dropdown-item" @click="switchLanguageTo(key)">
<img :src="getFlagImage(key)" /> {{value}}
</a>
</li>
我想我偶然發現了這個問題的最佳解決方案! 您唯一需要做的就是從根本上解決問題。
不起作用
<img :src="'../assets/' + pic + '.png">
工作:
<img :src="'src/assets/' + pic + '.png">
嘗試導入這樣的圖像,因為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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.