简体   繁体   中英

Vue.js - best way to set background image through filter

I'm learning Vue.js. On my site I have same images in two formats - jpg and webp. I want to generate correct image links depends on browser support (with or without .webp at end) through some filter. I do not need make this detection now, I just want to know what is the best way to set "background-image" and img "src" in Vue.

This is what I have now:

<template>
    <div>
        <div v-bind:style="{ backgroundImage: 'url(' + webp('/images/demo.jpg') + ')' }">
            <div class="container" style="min-height: 520px">
                <div class="row justify-content-center">
                    <div class="col-md-8">
                        <div class="card card-default">
                            <div class="card-header">Example Component</div>

                            <div class="card-body">
                                <img v-bind:src="'/images/demo2.jpg' | webp">
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

    </div>

</template>

<script>
    export default {

        methods: {
            webp(url) {
                // here will be code to detect webp support
                return url + '.webp';
            }
        },

        filters: {
            webp(url) {
                // here will be code to detect webp support
                return url + '.webp';
            }
        },

        mounted() {
            console.log('Component mounted.')
        }
    }
</script>

And It works, but it is correct approach? First problem is that I tried to use filter because it looks more clean to me. In img src it works, but in v-bind:style I had to use method. Now in script I have separate method and filter that does the same, that's bad... I tried to use filter but this doesn't work:

<div v-bind:style="{ backgroundImage: 'url(' + '/images/bg.jpg' | webp + ')' }">

I do not need to change image dynamically, so I tried also make it with standard style and use mustache:

<div style="background-image: url({{ '/images/bg.jpg' | webp }} ">

but this causes "Interpolation inside attributes has been removed."

What is the best, correct and clean way to achieve this, so I can use my webp detection as well in background-image and img src?

Not sure if this will work for you but I thought the way that this Kirby CMS plugin deals with WebP was clever - it detects WebP support in the server config and redirects any requests to *.jpg to *.webp . This example is for Apache but it should be possible to take the same approach with other server types.

<IfModule mod_rewrite.c>
  RewriteEngine On

  # Checking for WebP browser support ..
  RewriteCond %{HTTP_ACCEPT} image/webp

  # .. and if there's a WebP version for the requested image
  RewriteCond %{DOCUMENT_ROOT}/$1.webp -f

  # Well, then go for it & serve WebP instead
  RewriteRule (.+)\.(jpe?g|png)$ $1.webp [T=image/webp,E=accept:1]
</IfModule>

<IfModule mod_headers.c>
  Header append Vary Accept env=REDIRECT_accept
</IfModule>

<IfModule mod_mime.c>
  AddType image/webp .webp
</IfModule>

One possible way to solve your problem, change the template like this:

<div class="invite-container" :style="{backgroundImage: `url(${someBackgroundUrl})`} | imageFilter">

In the function imageFilter(value) , value is an Object, which is {backgroundImage: "url(https://somesite.com/img.png)"}

You can detect webp support first, and since you have the image url string, you could change the image format to webp now.

Finally, return an Object which is webp format. eg {backgroundImage: "url(https://somesite.com/img.png/webp)"}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM