Smaller and Faster

New features

Improved support for Typescript

Exposes lower-level APIs

More Maintainable codebase

let app = new Vue({ data:{ // Application data stays here }, computed:{ // computed properties stay here }, methods:{ // application functions and methods reside here }, watch:{ // watchers go here } })

let app = new Vue({ beforeCreate(){ }, setup(){ }, created(){ } })

Why the need for the composition API?

Fetching an API with the Options API

import axios from 'axios' import orderBy from 'lodash.orderby' export default { data () { return { characters: [], loadingState: null, orderKey: 'id' } }, computed: { charactersOrdered() { return orderBy(this.characters, this.orderKey) } }, methods: { fetchAllCharacters () { this.loadingState = 'loading' axios.get('https://rickandmortyapi.com/api/character') .then(response => { setTimeout(() => { this.loadingState = 'success' this.characters = response.data.results }, 1000) }) }, setOrderKey(key) { this.orderKey = key } }, created () { this.fetchAllCharacters() } }

Fetching with the Composition API

import axios from 'axios' import orderBy from 'lodash.orderby' import {computed, ref} from '@vue/composition-api' export default { setup () { const characters = ref([]) // use const because you dont want to lose this value const loadingState = ref(null) // Fetch Data Feature const fetchAllCharacters = () => { loadingState.value = 'loading' return axios.get('https://rickandmortyapi.com/api/character') .then(response => { loadingState.value = 'success' characters.value = response.data.results }) } // Order Fethced Data Feature const orderKey = ref('id') const charactersOrdered = computed(() => { return orderBy(characters.value, orderKey.value) }) const setOrderKey = (key) => { orderKey.value = key } return {characters, loadingState, fetchAllCharacters, charactersOrdered, orderKey, setOrderKey} }, created () { this.fetchAllCharacters() } }

Reactivity and State with the Composition API

Need to be imported to be used

Data using refs or reactive need to be returned as objects from setup function

Using Refs

<template> <button @click="increase"> Count is: {{ count.value }}, double is: {{ count.value * 2 }} </button> </template> <script> import { ref, watch } from 'vue' let count = ref(0) function increase() { count.value++ } const renderContext = { count, increment } watch(() => { renderTemplate( `<button @click="increment">8</button>`, renderContext ) }) </script>

Using Reactive

setup() { Const todos = reactive({ item: '' }) }

toRefs

return {…toRefs(todos)}

Installing and using the Composition API

npm install @vue/composition-api

import Vue from 'vue' import App from './App.vue' import VueCompositionApi from '@vue/composition-api'; Vue.use(VueCompositionApi); Vue.config.productionTip = false new Vue({ render: h => h(App), }).$mount('#app')

index.html

src

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%=%20BASE_URL%20%>favicon.ico"> <title>composition-todo</title> <link rel="stylesheet" href="https://bootswatch.com/4/lux/bootstrap.min.css"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body> <noscript> <strong>We're sorry but composition-todo doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>

app.vue

<template> <div id="app"> <section class = "container"> <div class="card"> <div class="card-header"> <h3> Add New Todo</h3></div> <div class="card-body"> <input type="text" class = "form-control" v-model ="state.todo"/> <button class="btn btn-primary my-2" @click="addNewTodo"> Add Todo</button> </div> </div> <div class="container my-5"> <div class="card"> <div class="card-header"> <h3> MyTodos</h3></div> <div class="card-body"> <ul class="list-group"> <li class="list-group-item" v-for="(todo, i) in state.todos" :key="i"> {{todo}} <i class="fa fa-trash" aria-hidden="true" @click="removeTodo(i)"></i> </li> </ul> </div> </div> </div> </section> </div> </template> <script> import { reactive } from "@vue/composition-api"; export default { setup(){ const {state, addNewTodo, removeTodo} = useTodo(); return { state, addNewTodo, removeTodo }; } } function useTodo(){ let state = reactive({ todo: "", todos: [] }); function addNewTodo(){ state.todos.push(state.todo); state.todo = ''; } function removeTodo(i){ state.todos.splice(i); } return{ state, addNewTodo, removeTodo }; } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } .fa { color:red; margin-left: 20px; /* height: 40px; */ } .fa:hover{ color: black; /* height: 50px; */ } </style>

npm run serve

todo app vue 3 composition API

Conclusion:

For a long time now, Vuejs has been one of the favorite frontend Javascript frameworks of many developers (including myself ) because of its reactivity and the general saying that the framework is relatively easier to pick up that most JavaScript frameworks . As at the time of writing this article, the current version of Vuejs is 2x, with Vue3x set to be released anytime soon. With Vue3x however, comes some amazing edges. i.eOne of the features Vue3x is bringing is the Vue 3which is a differentiation from the traditionalTraditionally with the Options API, the way to initialize an instance of Vue will be similar to the code block below:The Composition API introduces a setup option for working with components and the syntax looks similar to this:The setup option looks similar to lifecycle hooks but is far more powerful.Well, the Composition API helps organize code better and improves the reuse of logic throughout the entire codebase as well as improved support for typescript. Let’s see this in more detail:The block of code below shows an example of fetching data from an API using the conventional Options API.If we use the new composition API, the code would look similar to this:We see that the code above helps to organize and separate the features of our application. Let’s look at a further example of working with the composition API.Another Supercool feature of Vue3 is an upgrade to its well-loved reactivity. With the Composition API being released, reactivity and state can be handled by two new methods: refs and reactive. There are two ways to deal with state and reactivity in the setup function, refs and reactive. Using one over the other is a matter of preference and coding style. They both allow Vue to keep track of your state.It is important to have it in mind that knowing when to use refs and reactive, can be confusing and best practices are still being developedThe code block below is an example of when to use refs:Working with reactive Reactive takes an object and returns a reactive objectComputed properties can be included inside a reactive object Use themethod (creates a plain object with reactive properties) when destructuring or spreading an objectLet’s understand the composition API by building a To-Do Application Currently, to use the Vue3x composition API, we need to install it separately as the Vue CLI still uses Vue2. To do this, in your project directory, open up a terminal and run:Then modify your main.js file as thus:I would want us to add some styling and icons to our application, so go ahead and open up thefile in thefolder and update it as below:Next, open up yourfile and update the content as thus:You can serve your application withIn conclusion, while the Vue 3 composition API seems to be a much better way of working with components, it is important to note that the Composition API is only an alternative to the current Options API and not an overhaul. We can still work with components using options, mixins and scoped slots as it was before as the Vue core team has said the Options API would still be supported. You can find the source code of our application on its GitHub repository here