[Vuejs]-Dynamic css in vue-loader component not working

0👍

Try this out,

export default {
     props: ['message'],
     data(){
         var self = this; // Add this
         return{
             time: '',
             colorArray: ['hsl(210 , 82 , 50 )', 'hsl(130 , 50 , 51 )', 'hsl(337 , 50 , 46 )','hsl(133 , 50 , 65 )', 'hsl(28 , 50 , 70 )','hsl(180 , 50 , 59 )' , 'hsl(274 , 50 , 82 )'],
             colorClass:'',
             styles: {
                 'background-color' : self.colorArray[2] // change here
             },
         }
     },
...

0👍

The snippest you posted has no html which references styles, is another component trying to reference this component’s styles variable?

How can I bind the color of the class dynamically, by receiving a
number from the API?

If you add cssEl to your component’s data object you can do something like this:

watch: {
  // Keep track of the color (or colors) taken from the api
  colorTakenFromApi () {
    // Remove the old class if it exists;
    this.cssEl && this.cssEl.remove();
    // Create the element in the DOM, then tell the browser it's a stylesheet
    this.cssEl = document.createElement('style');
    this.cssEl.type = 'text/css';
    // Use a text template to insert the css rule you want
    this.cssEl.innerHTML = `
      .${this.cssClass} {
        background-color: `${this.colorTakenFromApi}`
      }
    `;
  }
}

I think it’s a bit of a hack, but this is what I used to change my css classes at runtime

0👍

In your case you can’t access this during initialization of data.

Work around would be:

Initialize your styles object as empty.

data(){
    return{
        time: '',
        colorArray: ['hsl(210 , 82 , 50 )', 'hsl(130 , 50 , 51 )', 'hsl(337 , 50 , 46 )','hsl(133 , 50 , 65 )', 'hsl(28 , 50 , 70 )','hsl(180 , 50 , 59 )' , 'hsl(274 , 50 , 82 )'],
        colorClass:'',
        styles: {},
    }
},

Then during created life-cycle set the initial style:

created() {
    this.time = moment(this.message.created_at).format('HH:mm');
    this.setColorClass(this.message.matchPosition);

    // Using Vue.set
    Vue.set(this, 'styles', {
        'background-color' : self.colorArray[2]
    });

    // OR Normal setting
    this.styles = {
        'background-color' : this.colorArray[2]
    };
},

0👍

I don’t know if I understands your problem but you can try computed methods:

props: ['message', 'colorNumber'],
computed: {
   getColorClass () {
      return 'color--' + this.colorNumber
   }
},

and in your template :

<template>
    <div :class="{'chat__message shadow': true,
                  'chat__message--own': message.selfOwned,
                   getColorClass: true}" >
    </div>
</template>

If you want to keep props as before and prop "message" is gonna change, you should use watch(deep kind) instead of computed one.

Otherwise if message props is not gonna change after page loaded then you can load it on data() variables and use it in computed method:

data(){
    return {
        colorNumber: '',
    }
},
mounted() {
   this.$nextTick(function () {
       // Code that will run only after the
       // entire view has been rendered

       this.colorNumber = this.message.matchPosition;
   })
},

Leave a comment