# 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.

```javascript
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

```javascript
<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

```javascript
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&#x20;

![](/files/-MOpzmM0TwDAKc1U7dha)

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.

![](/files/-MOq-L7Tkf_JLr6Otclc)

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

![](/files/-MOq0sj3ur1zmgK5jGcr)

```javascript
<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.

{% tabs %}
{% tab title="composables/useCounter.vue" %}

```javascript
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}
```

{% endtab %}

{% tab title="component.vue" %}

```javascript
<template>
  //...
</template>

<script>

import useCounter from "@/composables/useCounter";
import useFeature from "@/composables/useFeature";
//importing multiple composition functions

export default {
  setup() {
    return { ...useCounter(), ...useFeature() }
  }
};
</script>
```

{% endtab %}
{% endtabs %}

## 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.

```javascript
<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/>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mihai-gheorghe.gitbook.io/tic/composition-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
