Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically inject a mixin into component

Tags:

I have a component that requires a mixin depending on the props it receives.

const timerMixin = {
    created() {
        console.log("Timer mixin injected")
    }
}

export default {
    name: 'Component A',
    props: ['hasTimer'],
    mixins: this.hasTimer ? [timerMixin] : [] // fails because `this` is not available here 
}

Is there a way to dynamically inject a mixin into the component?

like image 710
Srinivas Damam Avatar asked Mar 13 '17 07:03

Srinivas Damam


2 Answers

You aren't going to be able to do this and it's actually by design, not accident, as stated by Evan You in this github issue:

I don't like the idea of runtime mixins, because it makes your components' behavior unpredictable depending on when mixins are applied.

This means that you can't assign a mixin after the fact and there is not any way to get the this context before the mixin loads.

I'm not entirely sure what you're aiming to do here, but if you simply don't want to init the timer mixin, then you can do the check in the mixins created hook before you take any further action (I personally would also add the hasTimer prop to the mixin aswell, but I'll keep it how you had it), so you get:

var timerMixin = {
  created(){
    if(this.hasTimer){
      this.initTimer();
    }
  },
  methods: {
    initTimer(){
      console.log('Init Timer Mixin')
    }
  }
}


export default {
    mixins: [timerMixin],
    props: ['hasTimer']
  });
}

Here's the JSFiddle: https://jsfiddle.net/gnkha6hr/

like image 102
craig_h Avatar answered Sep 17 '22 10:09

craig_h


Unfortunately, there is no way, currently, to dynamically add or remove mixins for a component. The this var is not available at that scope. And in the earliest lifecycle hook, beforeCreate, mixins are already loaded.

In your case, depending on what's in the timerMixin mixin, it might make sense to make a separate timer component with related logic which could be loaded dynamically in the template of Component A.

Otherwise, always loading the mixin probably wouldn't be too bad (performance-wise), since the data will be reactive.

like image 38
thanksd Avatar answered Sep 19 '22 10:09

thanksd