javascriptvue.jsvuejs3

vue3 - responsive background image from variable


I'm using Laravel and Vue, in the blade template I'm calling a Vue component which I'm passing some props too, to try and be able to update the background image depending on window width:

Blade Template:

<component 
    bg="{{ asset('/images/desktopBG.webp') }}"
    bgm="{{ asset('/images/mobileBG.webp') }}"
></component>

Component:

import { defineProps, computed } from 'vue';
const props = defineProps([ 'bg', 'bgm' ]);

const responsiveBG = computed(onresize = () => {
    if (window.innerWidth < 768) {
        console.log('background', props.bgm)
        return props.bgm
    } else {
        console.log('background', props.bg)
        return props.bg
    }
})

<template>
    <section id="container" :style="{backgroundImage: responsiveBG}"><section> 
</template>

The props are pulling through fine which I can see when console logging and it updates on window resizing, but I can't get it to be added a background image never mind change depending on the window width.

Any help would be appreciated? thanks


Solution

  • Try this:

    <script setup>
        import { defineProps, computed, onMounted, onBeforeUnmount, ref } from 'vue';
        
        const props = defineProps(['bg', 'bgm']);
        
        // Track window width with a reactive ref
        const windowWidth = ref(window.innerWidth);
        
        // Function to update window width on resize
        const updateWidth = () => {
            windowWidth.value = window.innerWidth;
        };
    
    
        // Computed property for responsive background
        const responsiveBG = computed(() => {
            return windowWidth.value < 768 ? `url(${props.bgm})` : 
            `url(${props.bg})`;
        });
        
        // Add and remove event listeners on mount and before unmount
        onMounted(() => {
            window.addEventListener('resize', updateWidth);
        });
        onBeforeUnmount(() => {
            window.removeEventListener('resize', updateWidth);
        });
        </script>
        
        <template>
            <section id="container" :style="{ backgroundImage: responsiveBG }">
                <slot></slot>
            </section>
        </template>