Tuesday, 24 October, 2017 UTC


Summary

When it’s a side project or something little, the DRY concept may not be tightly upheld. Yikes it’s just a “simple demo”, nothing large. When we begin to build large chunks of code not necessarily production level, thoughts of reusability and maintainability begin to come in. Must these methods be repeated? How do we replace this and that with functions? When using frameworks such as Vue, even with its ease of use and gradual learning curve, it becomes cumbersome to write and keep track of repetitive options in components. These options may be component data or hook methods such as “created”, “mounted” and even “methods”. This is where Mixins come in.
Mixins in Vue, gives us the ability to wrap our reusable options in a “variable container” which can be used anywhere in the script. And by anywhere, even globally, but that would be treated with caution.
What is a Mixin?
As the name goes - “Mix - In”, Mixin gives us a way to distribute reusable functionality in Vue components. These reusable functions are merged with existing functions. In our Vue component, we specify the mixin object with:
const myMixin = {
  created(){
    console.log("It works!")
  }
}
var app = new Vue({
  el: '#root',
  mixins: [myMixin]
})// It works!
Using mixins, whichever options specified in the mixin are immediately merged with the Vue component’s options. Multiple mixins can be specified in the mixin array of the component. Once specified, all mixin options are imported to the parent component.
Merging Options and Conflicts
Now we may think, what if there are conflicting options between hook functions from a mixin and that of the parent component, which takes precedence? When mixins are passed in components, Vue moves all hook functions such as created and mounted imported via the mixin into an array of options, including the options of the parent component. The parent component options are called last.
const myMixin = {
  created(){
    console.log("Welcome aboard")
  }
}

new Vue({
  el: '#root',
  mixins:[myMixin],
  created(){
    console.log("Ahoy mate!")
  }
})
//Welcome aboard
//Ahoy mate!
There are options which expect objects, like the methods object. In such cases where there is a conflict between options, the component options take precedence.
const myMixin = {
  created(){
    console.log("Welcome aboard")
  },
  methods:{
    name(){
      this.myName = prompt("Input Name")
    }
  }
}

new Vue({
  el:"#root",
  mixins:[myMixin],
  data:{
    myName:""
  },
  created(){
    console.log("Ahoy mate!")
  },
  methods:{
    name(){
      this.myName = "Christian John"
      console.log(this.myName)
    }
  }
})

//Console Logs
> Welcome aboard
> Ahoy mate!
> Christian John
Notice how the name() method in the mixin was disregarded during the conflict. The prompt to input name never runs.
Note: The Component Options are always right.
Here is a Codepen demo of a simple Vue counter app using mixin:
Global Mixins
In some cases, there is the need to extend the functionality of Vue or apply an option to all Vue components available in our application. Feels a bit scary? Yeah, mixins can be applied globally to affect all components in Vue.
Vue.mixin({
  created(){
  console.log("We wilding!")
  }
})

new Vue({
  el: '#data'
})

//Console
> We wilding!
The global mixin is created above the Vue instance, and we would have the mixin options spread across all components with the console running wild. This can be useful, during test, and debugging or third party libraries maybe, but we can see the potential harm that could be done if misused.
Using Mixins in CLI Development Mode
Using the Vue CLI, mixins can be specified anywhere in the project folder but preferably within /src/mixins for ease of access. Once mixins are created in a .js file and exposed with the export keyword, they can be imported in any component with the import keyword and its file path.
src/mixins/numeroUno.js
export const ={
  created(){
    console.log("Welcome aboard")
  },
  methods:{
    name(){
      this.myName = prompt("Input Name")
    }
  }
}
In the component, wherever it is in our project folder, we import the mixin object:
import {numeroUno} from <file path>

export default{
  name:'main',
  mixin:[numeroUno]
}
Even though we are importing a mixin object, lifecycle options are still available via the mixin and can be used in the component imported to.
Conclusion
Don’t Repeat Yourself. In a bid to follow this rule, we have seen how the power of Vue mixins can be utilized to minimize code and maximize the functionality of components. This comes in handy when multiple components are defined across our application with similar options. Components are created in the first place to introduce reusability, mixins are created to introduce reusability in our components. Mixins can also be created globally to function across all Vue components, such access if wrongly used can be dastardly.