Categories
Vue 3

Create Vue 3 Apps with the Composition API

Spread the love

Vue 3 comes with the Composition API built-in.

It lets us extract logic easily an not have to worry about the value of this in our code.

It also works better with TypeScript because the value of this no longer has to be typed.

In this article, we’ll look at how to create Vue 3 apps with the Composition API.

Basic Example

We can create a basic app by defining reactive properties and using them in templates.

For instance, we can write:

<template>
  <div>
    <button @click="increment">increment</button>
    {{ count }}
  </div>
</template>

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

export default {
  setup() {
    const count = ref(0);

    function increment() {
      count.value++;
    }

    return {
      count,
      increment,
    };
  },
};
</script>

We define the count reactive property with the ref function.

0 is its initial value.

And we add the increment function to update its value.

It’s updated differently than in the options API. We’ve to update the value property to update a reactive property with primitive values.

Then we return both count and increment so we can use them our template.

setup is a method that runs when we mount the component.

We can define object valued reactive properties with the reactive function.

To do this, we write:

<template>
  <div>
    <button @click="increment">increment</button>
    {{ state.count }}
  </div>
</template>

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

export default {
  setup() {
    const state = reactive({
      count: 0,
    });
    function increment() {
      state.count++;
    }

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

We call reactive with an initial object value.

Then we assign it to the state reactive property.

In the increment function, we update the state.count property to update its value.

And we return state and count so we can use them in the template.

Computed Property

To create a computed property, we can use the computed function.

To do this, we write:

<template>
  <div>
    <button @click="increment">increment</button>
    {{ state.count }}
    {{ double }}
  </div>
</template>

<script>
import { reactive, computed } from "vue";

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

    function increment() {
      state.count++;
    }

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

We pass a callback into the computed method to return the value we want for the computed property.

computed can be called in the object that we pass into reactive to add the computed property as a property of another reactive property.

Watchers

We can add a watcher into our Vue app with the watch function.

For instance, we can write:

<template>
  <div>
    <button @click="increment">increment</button>
    {{ state.count }}
  </div>
</template>

<script>
import { reactive, watch } from "vue";

export default {
  setup() {
    const state = reactive({
      count: 0,
    });
    function increment() {
      state.count++;
    }
    watch(
      () => state.count,
      (count) => {
        console.log(count);
      },
      { immediate: true }
    );
    return {
      state,
      increment,
    };
  },
};
</script>

to add it.

The first argument of watch is a function that returns the state.count reactive property.

In the 2nd argument, we get the latest value of state.count with count and log it.

The 3rd argument is an object with options for the watcher.

We can set deep and immediate in there as we do with the options API.

deep means watch all nested properties of an object for changes.

immediate means the watcher runs immediately when the component is mounted.

Conclusion

We can use the Vue 3 Composition API to define our components.

All the things we have in the options API are still available with some improvements.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *