Composition API

Composition API is a completely new concept that came along with version 3 of Vue.

It is similar to React Hooks to a certain extent. Please check out more at: https://composition-api.vuejs.org/#comparison-with-react-hooks

Please note that the concept is usable with Vue2 as well through a plugin.

import Vue from 'vue';
import VueCompositionApi from '@vue/composition-api';

Vue.use(VueCompositionApi);

Vue's Composition API addresses the following Vue 2 drawbacks:

  1. Large components (i.e. with large data objects and numerous methods) are not that readable, therefore hard to maintain.

  2. Logic is hard to be reused between components.

  3. Caveats with TypeScript support.

Composition API is additive, meaning we can continue using conventional component structure in parallel with this approach.

Basic syntax and Reactive References

Similar to the reactive data object, we can write a component with Composition API

<template>
  <div>Counter: {{ counter }}</div>
</template>

<script>
import { ref } from "vue";

export default {
  setup() {
    const counter = ref(3); // reactive reference
    return { counter }; //this is powerful because it allows us to expose
                        // to the template only the needed data
  }
};
</script>

Reactivity example with Composition API

import { ref, computed, watch } from 'vue';

let a = ref(5); // Create a reactive reference 'a'
let b = ref(8); // Create a reactive reference 'b'

let c = computed(() => a.value + b.value); // 'c' is a computed property, reactive

console.log(c.value); // 13 (access the value of 'c')

a.value = 10; // Update 'a' (triggers reactivity)

console.log(c.value); // Now 18! 'c' automatically updated

Structuring code by logical concerns

A conventional component might have its data and logic hard to

The features will have code fragments that we’d be splitting amongst all of our component options (components, props, data, computed, methods, and lifecycle methods). If we visualize this using colors (below) you can see how our feature code will get split up, making our component much more difficult to read and parse which code goes with which feature.

Through composition functions, available with Composition API, we can solve this issue.

<template>
  <div>
    <p>Counter: {{ counter }}</p>// It turns out that when Vue finds a ref
    // in a template it automatically exposes the inner value
    // so you should never need to call .value inside the template.
    <button @click="increment()">Increment</button>
  </div>
</template>

<script>
import { ref, computed } from "vue";
export default {
  setup() {
    const counter = ref(3);
    
    const doubleCounter = computed(() => { // similar to computed properties
      return counter.value * 2
    });

    function increment() { // composition function similar to a method
      counter.value++ // we don't access to 'this'
    }
    return { counter, doubleCounter, increment };
  }
};
</script>

Modularizing our codebase

Reusing our code across other components is achievable by extracting the logic into and importing it each time we need to use it in a component.

import { ref, computed } from "vue";
    
export default function useCounter() {
  const counter = ref(4);
  const doubleCounter = computed(() => {
    return counter.value * 2;
  });
  
  function increment() {
    counter.value++;
  }
  return { counter, dounbleCounter, increment}

Alternative syntax using reactive

Looking at the following example, we realize that the reactive state object can be passed as a reference through composition, thus making this an alternative method of transferring data across components.

<template>
  <button @click="increment">
    Count is: {{ state.count }}, double is: {{ state.double }}
    // the minor drawback from the ref alternative, is that we have
    // to use the '.' notation for accessing the data
  </button>
</template>

<script>
import { reactive, computed } from 'vue'

export default {
  setup() {
    const state = reactive({
      count: 0,
      double: computed(() => state.count * 2)
    })

    function increment() {
      state.count++
    }

    return {
      state,
      increment
    }
  }
}
</script>

For more, please make sure to check the official documentation at:

https://composition-api.vuejs.org/

Last updated

Was this helpful?