Search code examples
vuejs3vue-composition-api

VUEjs 3 Warning: Maximum recursive updates exceeded with dynamic css class


I'm rendering a list of cards in vue 3 and composition API, each item list display an Icon inside the img tag, I set this icon according to a property from every object of the list -> objeto.marca, the issue comes when set the dynamic class -> if I remove the dynamic class the issue go away. How can I get rid of this issue maintaining the dynamic class? Here is my code:

<script setup lang="ts">
import { onBeforeMount, ref } from "vue";
import { ISugerenciaGlobalStar } from "@/types/IMapas";
import aviaFrance from '@/assets/AVIA FRANCE.svg'
import petromiralles from '@/assets/PETROMIRALLES.svg'
import andamur from '@/assets/ANDAMUR.svg'
import cepsa from '@/assets/CEPSA.svg'
import esso from '@/assets/ESSO.svg'
import galp from '@/assets/GALP.svg'
import nieves from '@/assets/NIEVES.svg'
import q8 from '@/assets/Q8.svg'
import repsol from '@/assets/REPSOL.svg'
import shell from '@/assets/SHELL.svg'
import texaco from '@/assets/TEXACO.svg'
import valcarce from '@/assets/VALCARCE.svg'
import eni from '@/assets/ENI.svg'
import mtw from '@/assets/MTW.svg'
import tpetromiralles from '@/assets/T-PETROMIRALLES.svg'
import globalStar from '@/assets/web/logo-globalstar.png'

let reduceSizeIcon = ref<string>('')

const props = defineProps<{
    sugerenciasGlobarStar: ISugerenciaGlobalStar[];
}>();

function setImgIcon(marca: string): string {
    switch (marca) {
        case 'AVIA': { reduceSizeIcon.value = "" } return aviaFrance;
        case 'AVIA FRANCE': { reduceSizeIcon.value = "" } return aviaFrance;
        case 'PETROMIRALLES': { reduceSizeIcon.value = "" } return petromiralles;
        case 'T-PETROMIRALLES': { reduceSizeIcon.value = "" } return tpetromiralles;
        case 'ANDAMUR': { reduceSizeIcon.value = "" } return andamur;
        case 'CEPSA': { reduceSizeIcon.value = "" } return cepsa;
        case 'ESSO': { reduceSizeIcon.value = "" } return esso;
        case 'GALP': { reduceSizeIcon.value = "" } return galp;
        case 'NIEVES': { reduceSizeIcon.value = "" } return nieves;
        case 'Q8': { reduceSizeIcon.value = "" } return q8;
        case 'REPSOL': { reduceSizeIcon.value = "" } return repsol;
        case 'SHELL': { reduceSizeIcon.value = "" } return shell;
        case 'TEXACO': { reduceSizeIcon.value = "" } return texaco;
        case 'VALCARCE': { reduceSizeIcon.value = "" } return valcarce;
        case 'ENI': { reduceSizeIcon.value = "" } return eni;
        case 'MTW': { reduceSizeIcon.value = "" } return mtw;
        default: { reduceSizeIcon.value = "mapIconSugerencias" } return globalStar
    }
}
</script>
<template>
                        <v-card v-for="(objeto, key) in sugerenciasGlobarStar"
                                elevation="6" class="mt-2 pa-2">
                            <v-row justify="center" align="center" class="mr-0 ml-0">
                                <v-col cols="2" align="center">
                                    <!--

                                    -->
                                    <img :src="setImgIcon(objeto.marca)" :class="reduceSizeIcon" />
                                </v-col>
                                <v-col cols="10">
                                    <v-card-item class="ma-0 pa-0 text-caption">
                                        <template v-slot:prepend>
                                            {{ objeto.marca }}
                                        </template>
                                        <template v-slot:append>
                                            <v-icon v-if="objeto.favorito" color="amber-accent-4"
                                                class="mr-2 pb-2">mdi-star</v-icon>
                                            <span v-if="objeto.precio != '-'">
                                                {{ objeto.precio + " €" }}
                                            </span>
                                        </template>
                                    </v-card-item>
                                    <v-divider></v-divider>
                                    <v-card-item class="ma-0 pa-0 text-caption">
                                        <template v-slot:prepend>
                                            <span>{{
                                                objeto.provincia
                                            }}</span>
                                        </template>
                                        <template v-slot:append>
                                            <span>{{
                                                objeto.poblacion
                                            }}</span>
                                        </template>
                                    </v-card-item>
                                </v-col>
                            </v-row>
                        </v-card>
</template>
<style scoped>
.mapIconSugerencias {
    width: 100%;
}
</style>

Solution

  • I solve it cheking the way I set the css class, like this ->

    <img :src="setImgIcon(objeto.marca)" :class="objeto.marca ? 'mapIconSugerencias':''" />
    

    after that I could remove the setting class of every case inside the switch, much less code.