O backgroundImage do estilo de vinculação de dados Vue.js não funciona

94

Estou tentando vincular o src de uma imagem em um elemento, mas não parece funcionar. Estou recebendo uma "Expressão inválida. Corpo da função gerada: {backgroundImage: {url (imagem)}".

A documentação diz para usar 'Kebab-case' ou 'camel-case'.

<div class="circular" v-bind:style="{ backgroundImage: { url(image) }"></div>

Aqui está um violino: https://jsfiddle.net/0dw9923f/2/

CosX
fonte

Respostas:

215

O problema é que o valor de backgroundImageprecisa ser uma string como esta:

<div class="circular" v-bind:style="{ backgroundImage: 'url(' + image + ')' }"></div>

Aqui está um violino simplificado que está funcionando: https://jsfiddle.net/89af0se9/1/

Re: o comentário abaixo sobre o caso do kebab, é assim que você pode fazer isso:

<div class="circular" v-bind:style="{ 'background-image': 'url(' + image + ')' }"></div>

Em outras palavras, o valor de v-bind:styleé apenas um objeto Javascript simples e segue as mesmas regras.

ATUALIZAÇÃO: uma outra observação sobre por que você pode ter problemas para fazer isso funcionar.

Você deve certificar-se de que seu imagevalor esteja entre aspas para que a string final resultante seja:

url('some/url/path/to/image.jpeg')

Caso contrário, se o URL da imagem contiver caracteres especiais (como espaço em branco ou parênteses), o navegador pode não aplicá-lo corretamente. Em Javascript, a atribuição seria semelhante a:

this.image = "'some/url/path/to/image.jpeg'"

ou

this.image = "'" + myUrl + "'"

Tecnicamente, isso poderia ser feito no modelo, mas o escape necessário para mantê-lo HTML válido não vale a pena.

Mais informações aqui: Citar o valor de url () é realmente necessário?

David K. Hess
fonte
15
a partir de março de 2016, também precisa ser camel case ( backgroundImage) e não kebab case ( background-image), embora os documentos digam que pode ser.
andrewtweber
2
Se alguém for um idiota como eu, você poderia ter feito em backgroundImage: imagevez de backgroundImage: 'url('+image+')'. Fiquei tão preso à sintaxe vue que esqueci o url().
bendytree
Dentro de um componente Vue, funcionou para mim apenas dizer v-bind:style="{ 'background-image': url(image) }", mas fora de um componente (apenas em uma página normal) parecia exigir colocar url entre aspas. Alguém sabe por que isso pode ser?
Keara
2
@David Acho que realmente havia um método de url que escrevi e esqueci, e que faz exatamente o que eu esperava ... isso é muito hilário. Não posso realmente testá-lo em um violino porque os componentes do Vue estão em arquivos separados, mas tenho certeza de que era isso que estava causando o comportamento estranho, afinal. Obrigado!
Keara
1
Citações faltando era o meu problema. Obrigado por isso, estava perdendo horas aqui!
DonMB
32
<div :style="{'background-image': 'url(' + require('./assets/media/img.jpg') + ')'}"></div>
Mohammad Nazari
fonte
16

Outra solução:

<template>
  <div :style="cssProps"></div>
</template>

<script>
  export default {
    data() {
      return {
        cssProps: {
          backgroundImage: `url(${require('@/assets/path/to/your/img.jpg')})`
        }
      }
    }
  }
</script>

O que torna esta solução mais conveniente? Em primeiro lugar, é mais limpo. E então, se você estiver usando o Vue CLI (presumo que use), você pode carregá-lo com o webpack.

Nota: não se esqueça que require()é sempre relativo ao caminho do arquivo atual.

egdavid
fonte
5
<div :style="{ backgroundImage: `url(${post.image})` }">

existem várias maneiras, mas eu achei a string de modelo fácil e simples

chougle saud
fonte
1
Vim aqui para postar isso. Definitivamente, o melhor método com ES6.
corysimmons
O literal de modelo ES5 parece ser o novo caminho a seguir. As concatenações são coxas 🤓
zEELz
3

A vinculação do estilo da imagem de fundo usando um valor dinâmico do loop v-for pode ser feito assim.

<div v-for="i in items" :key="n" 
  :style="{backgroundImage: 'url('+require('./assets/cars/'+i.src+'.jpg')+')'}">
</div>
Abdelsalam Shahlol
fonte
Lamento muito, não me lembro de clicar no botão de voto negativo. Deve ter acontecido por acidente. Desfeito.
mtsz de
@mtsz não se preocupe.
Abdelsalam Shahlol
3

Para um único componente repetido, esta técnica funciona para mim

<div class="img-section" :style=img_section_style >

computed: {
            img_section_style: function(){
                var bgImg= this.post_data.fet_img
                return {
                    "color": "red",
                    "border" : "5px solid ",
                    "background": 'url('+bgImg+')'
                }
            },
}
coder618
fonte
2

Eu tentei @david resposta e não meu problema. depois de muito trabalho, criei um método e retornei a imagem com style string.

Código HTML

<div v-for="slide in loadSliderImages" :key="slide.id">
    <div v-else :style="bannerBgImage(slide.banner)"></div>
</div>

Método

bannerBgImage(image){
    return 'background-image: url("' + image + '")';
},
Devzakir
fonte
1

Tive um problema em que as imagens de fundo com espaços no nome do arquivo faziam com que o estilo não fosse aplicado. Para corrigir isso, tive que garantir que o caminho da string estava encapsulado em aspas simples.

Observe o \ 'de escape no meu exemplo abaixo.

<div :style="{
    height: '100px',
    backgroundColor: '#323232',
    backgroundImage: 'url(\'' + event.image + '\')',
    backgroundPosition: 'center center',
    backgroundSize: 'cover'
    }">
</div>
WDuffy
fonte
1

A resposta aceita não pareceu resolver o problema para mim, mas isso resolveu

Certifique-se de que suas declarações de backgroundImage sejam agrupadas em url (e aspas para que o estilo funcione corretamente, independentemente do nome do arquivo

Estilo ES2015:

<div :style="{ backgroundImage: `url('${image}')` }"></div>

Ou sem ES2015:

<div :style="{ backgroundImage: 'url(\'' + image + '\')' }"></div>

Fonte: vuejs / vue-loader issue # 646

bmatovu
fonte
0

Com base no meu conhecimento, se você colocar sua pasta de imagens em sua pasta pública, basta fazer o seguinte:

   <div :style="{backgroundImage: `url(${project.imagePath})`}"></div>

Se você colocar suas imagens no src/assets/, você precisará usar require. Como isso:

   <div :style="{backgroundImage: 'url('+require('@/assets/'+project.image)+')'}">. 
   </div>

Uma coisa importante é que você não pode usar uma expressão que contenha o URL completo como esta project.image = '@/assets/image.png'. Você precisa codificar a '@assets/'peça. Foi isso que encontrei. Acho que a razão é que no Webpack, um contexto é criado se o seu require contiver expressões, então o módulo exato não é conhecido em tempo de compilação. Em vez disso, ele pesquisará tudo na @/assetspasta. Mais informações podem ser encontradas aqui . Aqui está outro documento que explica como o carregador Vue trata o link em componentes de arquivo único.

Liang
fonte