Vue 3 came with Composition API, while still keeping support for the Options API. Vue 3 also recommends the use of Composition over Options API. Let’s have a look at why so.
1. Grouping of relevant code
It allows us to group the more relevant parts of the code easily in the script section of our components.
Let’s have a look at this code using the Options API:
<script>
export default {
name: "App",
data() {
return {
username: "",
password: "",
};
},
methods: {
updateUsername(newUsername) {
this.username = newUsername;
},
updatePassword(newPassword) {
this.password = newPassword;
},
},
mounted() {
this.updateUsername("Gautam");
this.updatePassword("");
},
};
</script>
Code language: HTML, XML (xml)
Now if we look at the above code, the relevant code (functioning of username) is present at three different places. That means if someone asks us to make some change to the username, we’ll have to scroll at all these three different places. It could become even worse for a complicated component with large amount of data. Vue 3 solves this with the Composition API.
The Composition API version of the above code would look like this:
<script setup>
import { ref, onMounted } from "vue";
//username code
const username = ref("");
function updateUsername(newUsername) {
username.value = newUsername;
}
onMounted(() => {
updateUsername("");
});
//password code
const password = ref("");
function updatePassword(newPassword) {
password.value = newPassword;
}
onMounted(() => {
updatePassword("");
});
</script>
Code language: HTML, XML (xml)
As we can see, the username part of the code is now grouped together. This grouping is more logical and helps us make changes to a particular part of the code more easily.
2. Code reusability using Composables
Vue 3 comes with the support for Composables. I basically allows us to share common functionality among multiple components, without using Mixins.
Let’s go back to our preveious example of the Options API. Let’s say we wanted to use a mixin to store and handle the username functionality. The mixin would look like this:
//mixin-username.js
export default {
data() {
return {
username: ""
};
},
methods: {
updateUsername(newUsername) {
this.username = newUsername;
}
}
};
Code language: JavaScript (javascript)
And for password functionality:
//mixin-password.js
export default {
data() {
return {
password: ""
};
},
methods: {
updatePassword(newPassword) {
this.password = newPassword;
}
}
};
Code language: JavaScript (javascript)
After creating the mixins, we could then import their functionalities and use them in a components:
<srcript>
import mixinUsername from '@/mixins/mixin-username';
import mixinPassword from '@/mixins/mixin-password';
export default {
mixins: [mixinUsername, mixinPassword];
mounted() {
this.updateUsername();
this.updatePassword();
}
}
</script>
Code language: JavaScript (javascript)
Now if we look at the above code, we’re calling a method named updateUsername. It’s hard to tell where this method is coming from. Here in this case, we’ve named the mixins in a relevent way so it might be a little easiler. However, in case of multiple mixins it’s not always possible to find it easily. And if you’re not familiar with the project you’re working on, it might even be impossible for you to guess. You’ll have to open the mixin files the browse through the code.
Let’s have a look at how Composition API solves this problem too.
Here’s how we’d create the useUsername composable:
//use/useUsername.js
import { ref } from "vue";
export function useUsername() {
const username = ref("");
function updateUsername(newUsername) {
username.value = newUsername;
}
return {
username,
updateUsername
};
}
Code language: JavaScript (javascript)
And below is how we’d import it in a component:
<script setup>
import { useUsername } from "./useUsername";
const { username, updateUsername } = useUsername();
onMounted(() => {
updateUsername("Gautam");
});
</script>
Code language: HTML, XML (xml)
We can destructure whichever functionalities we needed from the composable. We can easily see where the updateUsername method is coming from. Unlike using a mixin, the methods and their source path is much more clear here.
This is highly useful in advanced components and more complex apps.
If you have any suggestions or feedback, sound off in the comments section below!