Example of Mixins
Let's have a look at one of the basic examples of using Mixins in Vue.js. In the example below, we are creating a Mixin Object named myMixin; there is a method. There is another component called Component that reuses the mixin.
// define a mixin object
var myMixin = {
created: function () {
this.hello()
},
methods: {
hello: function () {
console.log('I am a Mixin in Vue.js')
}
}
}
// define a component that uses this mixin
// here reusability comes into play
var Component = Vue.extend({
mixins: [myMixin]
})
var component = new Component()

You can also try this code with Online Javascript Compiler
Run Code
Let's take a more elaborative example this time, consider that you have different components that are used to switch between a state boolean, a modal, and a tooltip. Notice that The logic to switch between states will be similar. However, they don't look the same. A mixin can be used,
//modal
const Modal = {
template: '#modal',
data() {
return {
isShowing: false
}
},
methods: {
toggleShow() {
this.isShowing = !this.isShowing;
}
},
components: {
appChild: Child
}
}
//tooltip
const Tooltip = {
template: '#tooltip',
data() {
return {
isShowing: false
}
},
methods: {
toggleShow() {
this.isShowing = !this.isShowing;
}
},
components: {
appChild: Child
}
}

You can also try this code with Online Javascript Compiler
Run Code
The logic can be extracted in a different place also as shown below:
const toggle = {
data() {
return {
isShowing: false
}
},
methods: {
toggleShow() {
this.isShowing = !this.isShowing;
}
}
}
const Modal = {
template: '#modal',
mixins: [toggle],
components: {
appChild: Child
}
};
const Tooltip = {
template: '#tooltip',
mixins: [toggle],
components: {
appChild: Child
}
};

You can also try this code with Online Javascript Compiler
Run Code
The complete code is
HTML
<div id="app">
<app-modal></app-modal>
<hr />
<app-tooltip></app-tooltip>
</div>
<script type="text/x-template" id="modal">
<div>
<h3>Let's trigger the modal!</h3>
<button @click="toggleShow">
<span v-if="isShowing">Hide child</span>
<span v-else>I will show child</span>
</button>
<app-child v-if="isShowing" class="modal">
<button @click="toggleShow">Close</button>
</app-child>
</div>
</script>
<script type="text/x-template" id="tooltip">
<div class="tooltip-demo">
<h3 @click="toggleShow">
<span v-if="isShowing">Click Me Again</span>
<span v-else>Click Me Please</span>
</h3>
<app-child v-if="isShowing" class="tooltip">
<p>I'm a tooltip this time</p>
</app-child>
</div>
</script>
<script type="text/x-template" id="childarea">
<div>
<h2>Here I am!</h2>
<slot></slot>
</div>
</script>
CSS
body {
font-family: 'Arial', sans-serif;
display: flex;
justify-content: center;
}
#app {
text-align: center;
margin: 60px;
max-width: 370px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
button {
font-family: 'Roboto Mono';
border: 1px solid black;
background: pink;
padding: 10px 5px;
margin: 0 10px;
outline: 0;
width: 70%;
cursor: pointer;
}
h4 {
margin: 0 0 15px;
}
.modal {
background: goldenrod;
color: white;
padding: 20px;
width: 200px;
position: absolute;
top: 50px;
z-index: 2000;
left: 50%;
transform: translateX(-120px)
}
hr {
margin-top: 30px;
width: 100%;
border-bottom: 1px solid #eee;
}
h3 span {
cursor: pointer;
}
form {
text-align: left;
line-height: 1.5em;
}
.tooltip-demo {
position: relative;
}
.tooltip {
position: absolute;
transform: translate3d(-20%, -160%, 0);
background: #000000;
color: white;
width: 280px;
border: 1px solid #8ef5c5;
}
.tooltip:after, .tooltip:before {
top: 100%;
left: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.tooltip:after {
border-color: rgba(0, 0, 0, 0);
border-top-color: #000000;
border-width: 10px;
margin-left: -10px;
}
.tooltip:before {
border-color: rgba(142, 245, 197, 0);
border-top-color: #8ef5c5;
border-width: 11px;
margin-left: -11px;
}
JS(Babel)
const Child = {
template: '#childarea'
};
const toggle = {
data() {
return {
isShowing: false
}
},
methods: {
toggleShow() {
this.isShowing = !this.isShowing;
}
}
}
const Modal = {
template: '#modal',
mixins: [toggle],
components: {
appChild: Child
}
};
const Tooltip = {
template: '#tooltip',
mixins: [toggle],
components: {
appChild: Child
}
};
new Vue({
el: '#app',
components: {
appModal: Modal,
appTooltip: Tooltip
}
});

You can also try this code with Online Javascript Compiler
Run Code

Merging in Mixins
An important point to be noted is that lifecycle hooks are also available to us from the mixin. So when applying it to overlapping processes, ordering matters. The ordering is as shown below.
Mixins will be applied first.
The component will be applied second.
When a mixin and the component itself contain overlapping options, they will be “merged” using appropriate strategies.The below example illustrates data objects undergoing a recursive merge, the component’s data is taking priority in conflicting situations.
var mixin = {
data: function () {
return {
message: 'hello',
foo: 'abc'
}
}
}
new Vue({
mixins: [mixin],
data: function () {
return {
message: 'goodbye',
bar: 'def'
}
},
created: function () {
console.log(this.$data)
// => { message: "goodbye", foo: "abc", bar: "def" }
}
})

You can also try this code with Online Javascript Compiler
Run Code
Hook functions and Mixins
Hook functions with the same name are merged into an array; all of them will be called. However, Mixin hooks will be called before the component's own hooks. This is illustrated in the example below
var mixin = {
created: function () {
console.log('I am the mixin hook')
}
}
new Vue({
mixins: [mixin],
created: function () {
console.log('i am the component hook')
}
})
// => "I am the mixin hook"
// => "I am the component hook"

You can also try this code with Online Javascript Compiler
Run Code
Objects that expect Object Value
There are also objects that expect object values, like Methods, Components, and directives. How will they be resolved??
The answer is they will be merged into the same object, wherein the component options will take priority in case there are conflicting keys in the objects.
var mixin = {
methods: {
foo: function () {
console.log('foo')
},
conflicting: function () {
console.log('from mixin')
}
}
}
var vm = new Vue({
mixins: [mixin],
methods: {
bar: function () {
console.log('bar')
},
conflicting: function () {
console.log('from self')
}
}
})
vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"

You can also try this code with Online Javascript Compiler
Run Code
Ain't the merge strategy used seems familiar??

(Source: Giphy)
The same merge strategies are used in Vue.extend().
Global Mixins
Global in terms of mixins does not mean being able to access every component. Instead, they are applied to every single component. As per the official documentation, You can also apply a mixin globally. Use with caution! Once you apply a mixin globally, it will affect every Vue instance created afterward. When used properly, this can be used to inject processing logic for custom options. To create a global instance, place it above the Vue instance. If you have used the Vue-CLI build, that means placing it in your main.js file.
Vue.mixin({
mounted() {
console.log('I am a Mixin')
}
})
new Vue({
...
})

You can also try this code with Online Javascript Compiler
Run Code
Global mixins are used sparsely, the reason being it affects every single Vue instance created, including the custom third-party components. It is a good idea to ship them as plugins to avoid duplicate applications.
FAQs
-
What are Mixins in VueJS?
Mixins are a flexible way to distribute reusable functionalities for Vue components. A mixin object can contain any component options. When a component uses a mixin, all options in the mixin will be “mixed” into the component's own options.
-
What is the benefit of using Mixins in VueJS?
With Vue mixins, you can easily adhere to the DRY principle in programming, which simply ensures that you do not repeat yourself. With Vue mixins, you also get a great option of flexibility, a mixin object contains options for Vue components, so there is a mixing of both mixin and component options.
Key Takeaways
In this blog, we studied Mixins in-depth, its theory, and the implementation part.
But this is not enough, right?
To truly master web development, you need to have a solid understanding of fundamentals and practice the learning by doing approach. For this, you can refer to our full-stack course on web development and be a Ninja Developer.