Introduction to the Vue Composition API

Introduction to the Vue Composition API

  • 479

The Vue Composition API is useful for creating components in a complex app. It’s organized that reduces clashes of names and provides better type inference in our components.

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll take a look at the Vue Composition API plugin for Vue 2.x to create our components in ways that are closer to the Vue 3.x way.

Vue Composition API

The Vue Composition API lets us move reusable code into composition functions, which any component can use with the setup component option.

With it, we don’t have to worry about name clashes between mixin members and component members because all the members are encapsulated in their own function and we can import them with new names.

Also, we don’t have to recreate component instances to reuse logic from different components.

The Composition API is built with large projects in mind, where there’re lots of reusable code.

In addition to the benefits that are listed above, we also have better type inference. It’s also more readable because we can trace all the code back to their composition function where the code is declared in the setup method.

The Vetur VS Code extension, which helps with developing Vue apps with VS Code, provides type inference when it’s used with the Composition API.

How to Use It?

With Vue 2.x projects, we can use it by installing the Vue Composition API package as follows for Vue CLI projects:

npm install @vue/composition-api

It’s also available for projects that don’t use the Vue CLI as a library that we can add via a script tag as follows:

<script src="https://unpkg.com/@vue/composition-api/dist/vue-composition-api.umd.js"></script>

The rest of the steps assumes that we’re building a Vue CLI project.

Once we installed it, we can use it by first registering the plugin as follows in main.js:

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");

Next, we’ll actually use the Vue Composition API plugin to build our components.

First, we create a file called Search.vue in the components folder as follows:

<template>
  <div class="hello">
    <form @submit.prevent="handleSubmit">
      <label>{{label}}</label>
      <input type="text" v-model="state.name">
      <input type="submit" value="search">
    </form>
  </div>
</template>
<script>
import { reactive } from "@vue/composition-api";
export default {
  name: "Search",
  props: {
    label: String
  },
  setup({ label }, { emit }) {
    const state = reactive({
      name: ""
    });
    return {
      handleSubmit(event) {
        emit("search", state.name);
      },
      state
    };
  }
};
</script>

In the code above, we have created a component that takes a prop called label , which is a string.

Then we can get the value of the prop by getting it from the first argument of the setup method instead of getting the prop as a property of this with the original Vue API.

Also, the emit method is retrieved from the object that’s passed into setup as the 2nd argument of it instead of a property of this .

To hold states, we call the reactive function from the Composition API package by passing in an object with the state properties to it.

state and reactive are equivalent to the object that we return in the data method with the regular Vue API.

The state constant is return as a property of the object so that we can reference the states as properties of state in our template.

To add methods with the Vue Composition API, we add them to the object that we return instead of as a property of the methods property like we did without the Vue Composition API.

We did that with the handleSubmit method.

In our template, we bind v-model to state.name rather than just name . But we reference the handleSubmit method like we do with methods before.

The search event is emitted when we type in something to the input and the click search.

Next, in App.vue , we write the following code:

<template>
  <div id="app">
    <Search label="name" @search="search"/>
    <div>{{state.data.name}}</div>
  </div>
</template>
<script>
import Search from "./components/Search";
import { reactive } from "@vue/composition-api";
export default {
  name: "App",
  components: {
    Search
  },
  setup() {
    const state = reactive({
      data: {}
    });
    return {
      state,
      async search(ev) {
        const res = await fetch(`https://api.agify.io/?name=${ev}`);
        state.data = await res.json();
      }
    };
  }
};
</script>

In the code above, we have similar structure as in Search.vue . Something that we didn’t have in this file is listening to events.

We have the search method which listens to the search event emitted from Search.vue . In the search method, we get some data, assign it to the state , and display it on the template.

Also, we assigned the retrieved data to state.data instead.

We can add computed properties with the computed function from the Vue Composition API package.

For instance, we can replace App.vue with the following to create a computed property and use it:

<template>
  <div id="app">
    <Search label="name" @search="search"/>
    <div>{{state.name}}</div>
  </div>
</template>
<script>
import Search from "./components/Search";
import { computed, reactive } from "@vue/composition-api";
export default {
  name: "App",
  components: {
    Search
  },
  setup() {
    const state = reactive({
      data: {},
      name: computed(() =>
        state.data.name ? `The name is: ${state.data.name}` : ""
      )
    });
    return {
      state,
      async search(ev) {
        const res = await fetch(`https://api.agify.io/?name=${ev}`);
        state.data = await res.json();
      }
    };
  }
};
</script>

In the code above, we changed App.vue slightly by importing the computed function to create a computed property.

To create the property, we added:

computed(() => state.data.name ? `The name is: ${state.data.name}` : "")

Then in the template, we referenced it by writing:

<div>{{state.name}}</div>

Now when we type in something and clicked search, we get ‘The name is (whatever you typed in)’ displayed.

Conclusion

The Vue Composition API is useful for creating components in a complex app. It’s organized that reduces clashes of names and provides better type inference in our components.

We still have everything that we’re used to like states, methods, events, templates and computed properties. It’s just that they’re in different places.