[6] Mixins and the reason for the birth of Composition API
Composition API summary
Composition API is an alternative syntax for VUE JS for component writing. It is optional, so you are not obliged to use it. It is not a replacement for the Options API, so you can also continue using it.
To dispel some myths, it neither improves the performance nor the security. The Composition API was born because Vue 2 had far from ideal TypeScript support and the Vue Team wanted to provide a better one. So this was the main reason why they wrote it. Besides, it also has several other benefits next to the TypeScript support, like code organization and reusability. Although Vue 2 has provided mixins for reusability, that is still available in Vue 3. Mixins are not as flexible as they should be.
Let’s see how Mixins work
Mixins are a flexible way to distribute functionalities for Vue components, but they have drawbacks. Mixins do not work on their own and do not mean to. They are objects that will merge with an instance of Vue or a component. Mixins object must match the option names in a components options object.
In the following code, we will create a root component that will use the options properties of the mixin as it were the property of a component.
export default {
data(){
return{
offset: 0,
}
},
mounted(){
window.addEventListener('scroll', this.update);
},
methods:{
update(){
this.offset = window.pageYOffset;
}
}
}
this is the code of the mixins.js
<template>
<div id="app">
<div class="scrollPosition">
{{offset}}
</div>
</div>
</template>
<script>
import mixin from "./mixin";
export default {
name: 'App',
mixins:[mixin]
};
</script>
<style>
#app {
width: 100%;
height: 3000px;
position: relative;
}
.scrollPosition{
position:fixed;
left: 10px;
right: 10px;
}
</style>
code of the root component App. vue
Between the script tags in the main component, we have imported the separated mixin file and we set the mixins array property. So we could use the offset property which was initialized in the mixin file.
The reason for the Composition API
Due to mixins drawbacks, Vue launched the Composition API. Let’s define an offset property with a different value in the component.
...
export default {
name: 'App',
mixins: [mixin],
// This will have priority over the mixin version
data() {
return {
offset: 110,
};
},
};
</script>
<style>
...
If we run the code leaving the mixin as it is above. We can see the component property will have “priority” over the Mixin value. (In fact, this is a drawback that we call Namespace collision). It is because Mixin properties have lower levels than the component’s properties. So the value of the component property will be used. If there is no collision in the property names, they will live next to each other.
Components data stay isolated all the time. So there will be no leaking between them. They remain isolated and share data between the mixin and the data with multiple copies of that property. One component does not influence any other component’s data, even if they are registering the same mixin. And they will have a unique version of data. So mixins can be useful for generating generic functions that can be shared across multiple components.
How do lifecycle functions are treated with mixins?
If a mixin and a component have the same lifecycle definition then both will run. This allows defining lifecycle functions without them conflicting with another freely. We can test it with the following code that you need to add to the App.vue component’s code.
mounted() {
console.log('App mounted lifecycle function');
}
If you build and run the application you should see this message in the console while the scroll position and that means Mixin’s lifecycle hooks work with component one. So they both run.
The issue with Mixins
- Namespace collision
- You will not be notified
- You have to rename the property and make sure you have unique values
- Collision can happen between multiple mixin properties too
Conclusion & Closing
In the previous VueJS related topic, I have already written about the Composition API. In this post, I have added some extra details while I have tried to detail VueJS’s Mixins feature and the issue with Mixins that partly inspired the developers of VueJS to implement the Composition API.