By Filip Rakowski

Kai Dao College


We already know that applications written in the new version of Vue will perform very well, but performance is not the most important part. What matters most to us developers is how the new release will affect the way we write code.

As you might expect, Vue3 brings a lot of new and exciting features. Fortunately, the Vue team has mostly made additions and improvements to the current Composition API, rather than major changes, so anyone who already knows about Vue2 should quickly be satisfied with the new syntax.

Let’s start with the Composition API that most people have probably heard of!

Composition API

The most common one discussed in the next major version of Vue is the feature syntax of Composition AP. This is a new approach to logic reuse and code organization.

Currently, we use the “Options” API to build components. To add logic to the Vue component, we populate (options) properties, such as Data, Methods, computed, and so on. The biggest drawback to this approach is that it is not a working JavaScript code per se. You need to know exactly what attributes are accessible in the template and how the this keyword behaves. Underneath, the Vue compiler needs to convert this property into working code. Because of this, we can’t benefit from automated suggestions or type checking.

The Composition API wants to solve this problem by exposing the mechanisms available through the current component properties as JavaScript functions. The Vue core team describes the component Composition API as “a set of additional, function-based apis that allow for flexible Composition of component logic.” Code written using the Composition API is easier to read and scenarios are less complex, making it easier to read and learn.

Let’s take a look at a very simple component example that uses the new component Composition API to understand how it works.

<template> <button @click="increment"> Count is: {{ count }}, double is {{ double }}, click to increment. </button> </template> <script> import { ref, computed, onMounted } from 'vue' export default { setup() { const count = ref(0) const double = computed(() => count.value * 2) function increment() { count.value++ } onMounted(() => console.log('component mounted! ')) return { count, double, increment } } } </script>Copy the code

Now let’s break this code down into sections to understand what’s going on.

import { ref, computed, onMounted } from 'vue'Copy the code

As I mentioned earlier, the Composition API exposes component properties as functions, so the first step is to import the functions we need. In our case, we need to create reactive references with REF, calculate attributes using computed, and access loaded lifecycle hooks with onMounted.

Now you may be wondering what is this mysterious setup method?

Export Default {setup() {}} ' 'in a nutshell, it is just a function that returns properties and functions to the template. Here we declare all the reactive properties, computed properties, observer, and lifecycle hooks, and then return them so that they can be used in the template. What we do not return in the setup function will not be available in the template. ```js const count = ref(0)Copy the code

Based on the above, we will use the ref function to declare a reactive attribute called count. It can wrap any primitive type or object and return a reactive reference to it. The value of the pass element is retained in the value attribute that creates the reference. For example, if you want to access the value of the count reference, you need to extend the request count.value.

const double = computed(() => count.value * 2)

function increment() {
  count.value++
}Copy the code

This is what we do when we declare functions that evaluate the properties double and increment

onMounted(() => console.log('component mounted! '))Copy the code

Mounted hooks allow you to log messages when the component is loaded

return {
  count,
  double,
  increment
}Copy the code

Finally, we return the count and double attributes and increment methods to make them available in the template.

<template>
  <button @click="increment">
    Count is: {{ count }}, double is {{ double }}. Click to increment.
  </button>
</template>Copy the code

Now we can access the properties and functions returned by Setup in template just as they were declared through the old Options API.

This is a simple example that can be easily implemented using the Options API. The real benefits of the new Composition API are not only in writing code differently, but also in reusing our code/logic.

Composition API code reuse

The new Composition API has even more advantages. Think about code reuse. Currently, if we want to share some code between other components, there are two options available — interfuse and scope slots. Both have their drawbacks.

Suppose we want to extract the count function and reuse it in other components, you can see how it works with the available apis and Composition APIS below.

We start with blending…

import CounterMixin from './mixins/counter'

export default {
  mixins: [CounterMixin]
}Copy the code

The biggest disadvantage of mixin is that we don’t know what it adds to our components. Not only is it difficult to interpret, but it can also lead to name conflicts with existing properties and functions.

Look at the range slot

<template>
  <Counter v-slot="{ count, increment }">
     {{ count }}
    <button @click="increment">Increment</button> 
  </Counter> 
</template>Copy the code

With range slots, we know exactly which attributes we can access through the V-slot attribute, which makes it easier to understand the code. The downside of this approach is that we can only access it in the template, and it can only be used within the scope of the Counter component.

It’s time to use the Composition API

function useCounter() {
  const count = ref(0)
  function increment () { count.value++ }

  return {
    count,
    incrememt
  }
}

export default {
  setup () {
    const { count, increment } = useCounter()
    return {
      count,
      increment
    }
  }
}Copy the code

More elegant, isn’t it? We are not constrained by the scope of templates and components, and we know exactly what properties we can access from counters. In addition, we can benefit from the compiled code because useCounter is just a function that returns some properties. So the editor can help us with type checking and suggestions.

This is also a more elegant way to use third-party libraries. For example, if we wanted to use vuex, we could extend the useStore function instead of polluting the Vue prototype (this.$store).

const { commit, dispatch } = useStore()Copy the code