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:
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:
Large components (i.e. with large data objects and numerous methods) are not that readable, therefore hard to maintain.
Logic is hard to be reused between components.
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.
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: