Vue.js data-bind style backgroundImage no funciona

89

Estoy tratando de vincular el src de una imagen en un elemento, pero parece que no funciona. Recibo una "Expresión no válida. Cuerpo de función generado: {backgroundImage: {url (image)}".

La documentación dice usar 'Kebab-case' o 'camel-case'.

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

Aquí hay un violín: https://jsfiddle.net/0dw9923f/2/

CosX
fuente

Respuestas:

208

El problema es que el valor de backgroundImagedebe ser una cadena como esta:

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

Aquí hay un violín simplificado que está funcionando: https://jsfiddle.net/89af0se9/1/

Re: el comentario a continuación sobre kebab-case, así es como puedes hacer eso:

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

En otras palabras, el valor de v-bind:stylees solo un objeto Javascript simple y sigue las mismas reglas.

ACTUALIZACIÓN: Otra nota sobre por qué puede tener problemas para hacer que esto funcione.

Debe asegurarse de que su imagevalor esté entre comillas para que la cadena final resultante sea:

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

De lo contrario, si la URL de su imagen tiene caracteres especiales (como espacios en blanco o paréntesis), es posible que el navegador no la aplique correctamente. En Javascript, la asignación se vería así:

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

o

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

Técnicamente, esto podría hacerse en la plantilla, pero el escape requerido para mantenerlo HTML válido no vale la pena.

Más información aquí: ¿Es realmente necesario citar el valor de url ()?

David K. Hess
fuente
15
A partir de marzo de 2016, también debe ser un caso de camello ( backgroundImage) no un caso de kebab ( background-image), aunque los documentos dicen que puede serlo.
andrewtweber
2
Si alguien es un tonto como yo, podría haberlo hecho en backgroundImage: imagelugar de backgroundImage: 'url('+image+')'. Me obsesioné tanto con la sintaxis de vue que olvidé el url().
bendytree
Dentro de un componente de Vue, me funcionó solo decirlo v-bind:style="{ 'background-image': url(image) }", pero fuera de un componente (solo en una página normal) parecía requerir poner la URL entre comillas. ¿Alguien sabe por qué podría ser eso?
Keara
2
@David Creo que en realidad había un método de URL que escribí y me olvidé, y que hace exactamente lo que esperaba ... eso es bastante divertido. Realmente no puedo probarlo en un violín debido a que los componentes de Vue están en archivos separados, pero estoy seguro de que eso es lo que estaba causando el comportamiento extraño después de todo. ¡Gracias!
Keara
1
Las citas faltantes eran mi problema. ¡Gracias por esto, estaba perdiendo horas aquí!
DonMB
29
<div :style="{'background-image': 'url(' + require('./assets/media/img.jpg') + ')'}"></div>
mohammad nazari
fuente
14

Otra solución:

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

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

¿Qué hace que esta solución sea más conveniente? En primer lugar, es más limpio. Y luego, si está utilizando Vue CLI (supongo que sí), puede cargarlo con webpack.

Nota: no olvide que require()siempre es relativo a la ruta del archivo actual.

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

hay varias formas, pero encontré la cadena de plantilla fácil y simple

chougle saud
fuente
1
Vine aqui para publicar esto. Definitivamente el mejor método con ES6.
corysimmons
La plantilla literal de ES5 parece el nuevo camino a seguir. Las concatenaciones son malas 🤓
zEELz
3

La vinculación del estilo de la imagen de fondo utilizando un valor dinámico del bucle v-for se podría hacer así.

<div v-for="i in items" :key="n" 
  :style="{backgroundImage: 'url('+require('./assets/cars/'+i.src+'.jpg')+')'}">
</div>
Abdelsalam Shahlol
fuente
Lo siento mucho, no recuerdo haber hecho clic en el botón de voto negativo. Debe haber ocurrido por accidente. Deshecho.
mtsz
@mtsz no se preocupe.
Abdelsalam Shahlol
2

Para un solo componente repetido, esta técnica funciona para mí.

<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+')'
                }
            },
}
codificador618
fuente
2

Traté @ David respuesta, y no fijó mi problema. después de muchas molestias, hice un método y devolví la imagen con la cadena de estilo.

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
fuente
1

Experimenté un problema en el que las imágenes de fondo con espacios en el nombre del archivo provocaban que no se aplicara el estilo. Para corregir esto, tuve que asegurarme de que la ruta de la cadena estuviera encapsulada entre comillas simples.

Tenga en cuenta el \ 'escapado en mi ejemplo a continuación.

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

La respuesta aceptada no pareció resolver el problema para mí, pero esto sí

Asegúrese de que sus declaraciones de backgroundImage estén envueltas en URL (y comillas para que el estilo funcione correctamente, sin importar el nombre del archivo.

ES2015 Estilo:

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

O sin ES2015:

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

Fuente: vuejs / vue-loader issue # 646

bmatovu
fuente