Eu tenho um caso onde em minha Vue.js
com webpack
aplicativo web, eu preciso exibir imagens dinâmicas. Eu quero mostrar img
onde o nome do arquivo de imagens são armazenados em uma variável. Essa variável é uma computed
propriedade que está retornando uma Vuex
variável de armazenamento, que está sendo preenchida de forma assíncrona em beforeMount
.
<div class="col-lg-2" v-for="pic in pics">
<img v-bind:src="'../assets/' + pic + '.png'" v-bind:alt="pic">
</div>
No entanto, funciona perfeitamente quando eu apenas faço:
<img src="../assets/dog.png" alt="dog">
Meu caso é semelhante a este fiddle , mas aqui funciona com img URL, mas no meu com caminhos de arquivo reais, não funciona.
Qual deve ser a maneira correta de fazer isso?
javascript
html
vue.js
vuejs2
Saurabh
fonte
fonte
@/assets/
+ items.image) "height =" 200px "> </v-img>` este também resolveu o problemaRespostas:
Eu fiz isso funcionar seguindo o código
getImgUrl(pet) { var images = require.context('../assets/', false, /\.png$/) return images('./' + pet + ".png") }
e em HTML:
<div class="col-lg-2" v-for="pic in pics"> <img :src="getImgUrl(pic)" v-bind:alt="pic"> </div>
Mas não sei por que minha abordagem anterior não funcionou.
fonte
Aqui está um atalho que o webpack usará para que você não precise usar
require.context
.HTML:
<div class="col-lg-2" v-for="pic in pics"> <img :src="getImgUrl(pic)" v-bind:alt="pic"> </div>
Método Vue:
getImgUrl(pic) { return require('../assets/'+pic) }
E eu acho que os primeiros 2 parágrafos aqui explicam por que isso funciona? bem.
Observe que é uma boa ideia colocar as fotos do seu animal de estimação em um subdiretório, em vez de inseri-las com todos os outros ativos de imagem. Igual a:
./assets/pets/
fonte
@/assets/
+ items.image) "height =" 200px "> </v-img>` este também resolveu o problemaVocê pode experimentar a
require
função. como isso:<img :src="require(`@/xxx/${name}.png`)" alt class="icon" />
fonte
@
símbolo é obrigatório?@
símbolo não é necessário, muitas vezes representa seusrc
diretório ao usar Resolve | webpack (vue-cli já está configurando isso.).Há outra maneira de fazer isso adicionando seus arquivos de imagem à pasta pública em vez de ativos e acessá-los como imagens estáticas.
<img :src="'/img/' + pic + '.png'" v-bind:alt="pic" >
É aqui que você precisa colocar suas imagens estáticas:
fonte
Sua melhor aposta é apenas usar um método simples para construir a string correta para a imagem no índice fornecido:
methods: { getPic(index) { return '../assets/' + this.pics[index] + '.png'; } }
em seguida, faça o seguinte dentro do seu
v-for
:<div class="col-lg-2" v-for="(pic, index) in pics"> <img :src="getPic(index)" v-bind:alt="pic"> </div>
Aqui está o JSFiddle (obviamente as imagens não aparecem, então coloquei a imagem
src
ao lado da imagem):https://jsfiddle.net/q2rzssxr/
fonte
Eu também encontrei este problema e parece que as duas respostas mais votadas funcionam, mas há um pequeno problema, webpack lança um erro no console do navegador (Erro: Não é possível encontrar o módulo './undefined' em webpackContextResolve) o que não é muito bom.
Então, resolvi um pouco diferente. Todo o problema com a variável dentro da instrução require é que a instrução require é executada durante o empacotamento e a variável dentro dessa instrução aparece apenas durante a execução do aplicativo no navegador. Portanto, o webpack vê a imagem necessária como indefinida de qualquer maneira, já que durante a compilação essa variável não existe.
O que eu fiz foi colocar a imagem aleatória no comando require e esconder essa imagem no css, para que ninguém a visse.
// 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}
A imagem vem como parte das informações do banco de dados via Vuex e é mapeada para o componente como um computador
computed: { user() { return this.$store.state.auth.user; } }
Assim que esta informação estiver disponível, troco a imagem inicial para a real
watch: { user(userData) { this.userAvatar = require(`@/assets/${userData.avatar}`); this.hidden = false; } }
fonte
Aqui está uma resposta muito simples. : D
<div class="col-lg-2" v-for="pic in pics"> <img :src="`../assets/${pic}.png`" :alt="pic"> </div>
fonte
Você pode usar o bloco try catch para ajudar com imagens não encontradas
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 },
fonte
<img src="../assets/graph_selected.svg"/>
O caminho estático é resolvido pelo Webpack como uma dependência do módulo por meio do carregador. Mas para o caminho dinâmico, você precisa usar require para resolver o caminho. Você pode então alternar entre as imagens usando uma variável booleana e uma expressão ternária.
<img :src="this.graph ? require( `../assets/graph_selected.svg`) : require( `../assets/graph_unselected.svg`) " alt="">
E, claro, alternar o valor do booleano por meio de algum manipulador de eventos.
fonte
:src="require(
../assets/category_avatar/baby_kids.jpeg)"
Vue.js usa
vue-loader
, um carregador para WebPack que é configurado para reescrever / converter caminhos em tempo de compilação, a fim de permitir que você não se preocupe com caminhos estáticos que seriam diferentes entre as implantações (local, dev, uma plataforma de hospedagem ou outra) , permitindo que você use caminhos relativos do sistema de arquivos local . Ele também adiciona outros benefícios, como cache de ativos e controle de versão (você provavelmente pode ver isso verificando osrc
URL está sendo gerado).Portanto, ter um src que normalmente seria tratado por
vue-loader
/ WebPack definido como uma expressão dinâmica, avaliada em tempo de execução, contornará esse mecanismo e o URL dinâmico gerado será inválido no contexto da implantação real (a menos que seja totalmente qualificado, isso é uma exceção )Se, em vez disso, você usar uma
require
chamada de função na expressão dinâmica,vue-loader
/ WebPack a verá e aplicará a mágica usual.Por exemplo, isso não funcionaria:
<img alt="Logo" :src="logo" />
computed: { logo() { return this.colorMode === 'dark' ? './assets/logo-dark.png' : './assets/logo-white.png'; } }
Embora isso funcione:
<img alt="Logo" :src="logo" />
computed: { logo() { return this.colorMode === 'dark' ? require('./assets/logo-dark.png') : require('./assets/logo-white.png'); } }
Eu só descobri isso sozinho. Demorou uma hora mas ... você vive, você aprende, certo? 😊
fonte
bem, a melhor e mais fácil maneira que funcionou para mim foi buscar dados de uma API.
methods: { getPic(index) { return this.data_response.user_Image_path + index; } }
o método getPic pega um parâmetro que é o nome do arquivo e retorna o caminho absoluto do arquivo talvez do seu servidor com o nome do arquivo simples ...
aqui está um exemplo de um componente onde usei isto:
<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>
fonte
Eu encontrei o mesmo problema. Isso funcionou para mim, alterando '../assets/' para './assets/'.
<img v-bind:src="'./assets/' + pic + '.png'" v-bind:alt="pic">
fonte
Tentei todas as respostas aqui, mas o que funcionou para mim no Vue2 é assim.
<div class="col-lg-2" v-for="pic in pics"> <img :src="require(`../assets/${pic.imagePath}.png`)" :alt="pic.picName"> </div>
fonte