Search code examples
javascriptcsseventsvuejs3

A way to change component colour based on CustomEvent value in Vue.js 3?


Im making a Snackbar component that gets activated from CustomEvent, im stuck at changing colours based on type of error, i assume "type":"success" is wrong

event Code:

        var Snackbardata2 = new CustomEvent('Showtext', {'detail': {"snackbarmsg":"fries: "+path+" Value changed to "+val,"type":"success"}})

Event listener:

methods: {
      show(message, type = 'success', duration = 10000) {
        this.type = type;
        this.message = message;
        this.visible = true;
        clearTimeout(this.timeout);
        this.timeout = setTimeout(() => {
          this.visible = false;
        }, duration);
      },
    },
mounted(){
        window.addEventListener('Showtext',
            function(data,type) {
                this.show(data["detail"]["snackbarmsg"],type["detail"]["type"]);}.bind(this));
    }

CSS:

computed:{
      snackbarClass(){
        return{
          'w3-green': this.type === 'success',
          'w3-red': this.type === 'error',
          'w3-yellow': this.type === 'warning',
        }
      }

Is there any way to change colour or CSS in general via custom events in Vue ?

My knowledge of JS is very limited and i am new to Vue 3 so i assume the problem lies with me. The the only error i keep encountering is: error Unexpected mutation of "type" prop vue/no-mutating-props. Any nudge in the right direction is welcomed.


Solution

  • The issue is how you're accessing the type from the event detail in your event listener (also, I find your approach very bizarre overall, but maybe it's just me). The type should be accessed directly from the data object received in the event handler, rather than trying to index into type["detail"]["type"].

    Modify your event listener in the mounted hook of your Vue component like this:

    mounted() {
      window.addEventListener('Showtext', event => {
        const data = event.detail;
        this.show(data.snackbarmsg, data.type);
      });
    }
    

    Here's a link to the Vue playground with working example: https://play.vuejs.org/...

    Modify the type values in the event dispatch to see the changes being applied to the snackbar:

    const Snackbardata = new CustomEvent('Showtext', {
            detail: {
            snackbarmsg: 'Snackbar message here',
            type: 'success' // Change to 'error' or 'warning'
          }
        });
        window.dispatchEvent(Snackbardata);
    

    Also please do provide reproducible snippet next time.