Vue 3 and Composition API

Cover image

I have recently attended Vue Conference in Toronto that included topics from Vue 3, what to expect from Vue in the future, to general E2E testing with Cypress and have better error stack trace when catching error. What caught my attention the most, and yours probably, is Vue 3 and Composition API!

Vue Toronto Conference 2019

Vue 3

The Vue team has done tremendous work on the next version of Vue which is expected to be released in Q1 in 2020. If you understand how hard it is to manage a codebase for an enterprise application then you would understand how difficult it is to manage a library that’s used by many people with totally different needs. Give them an applause 👏

TypeScript

Vue 3 has been rewritten from the ground up in TypeScript. Besides writing tests, the team finds out using TypeScript helps them release code more confidently because you can catch error at build time or even during development. Another benefit of TypeScript is the tooling, specifically the typing file. It contains information about your code like what methods your class has, what arguments it needs, and what the return types are.

ES Modules

As more features are being added to Vue codebase, the bundle will for sure bloat and not every single feature is used by everybody. Users shouldn’t include and pay for code that are not used so the global API and internal helpers are now in ES modules and Webpack will be able to analyze and tree-shake the unused code. The same applies to v-if, v-model, and other template directives as well.

Performance Improvement

Vue has introduced a way to handle huge chunk of data while still being responsive to user’s interactions called time slicing. Imaging you have 10,000 rows of data on a table and you need to update all of them at once. Currently it would block the UI thread to resolve all of these updates making it unresponsive. In Vue 3 it will split them into multiple chunks and handle them in requestAnimationFrame to free up and the UI thread for a bit while still dealing with the UI updates.

The team has also revamped the way it’s making virtual DOM comparison and updates. Virtual DOM is a JavaScript representation of the UI and Vue uses this to make comparison and updates every time we change a data value. Doing comparison in VDOM is cheaper than doing the actual diffing on the real DOM so it is more efficient. However diffing is currently done on all of the VDOM elements including those that are not data binding to any data. The team is able to map out a tree that denotes what can be updated and only diff those parts. As a result, VDOM update is not proportional to amount of template you have amount of dynamic content you have now.

Composition API

New version comes new API. Inspired by React's hooks, Vue has introduced Composition API which allows you to easily organize your code around and share it with other components while maintaining its reactivity.

Vue Options API

The current way of grouping our code around in a Vue component typically looks something like the picture above. You put your data in data property, the relevant methods in methods property, and other relevant values in your computed property. Imagine your component has a lot more data and difficult to break them down. You would find yourself scrolling up and down. From organization point of view, this is not efficient since relevant codes are not grouped.

Vue Composition API

With Composition API, you can group code that is for the same feature together. You don’t need to have too much memory overhead in your head to keep track of where everything is.

We can first create a function that has our logic in it.

import { ref } from “vue”;  

function useCounter() {
  let counter = ref(0);

  function increment() {
    counter.value += 1;
  }

  function clear() {
    counter.value = 0;
  }

  return { counter, increment, clear };
}

This ref is a new way to make a primitive value reactive so Vue can track of the changes. In this useCounter function we create the data and the necessary methods that mutate that data, and we return them in a nice object. To use this function we put it in the new property called setup:

export default {
	setup() {
    console.log(“setup”);
    let { counter, increment, clear } = useCounter();

    return { counter, increment, clear };
  },

  beforeCreate() {
    console.log("beforeCreate”);
  },

  created() {
    console.log(“created”);
  },  
};

To actually expose these values and methods to be usable inside the component, we need to return them inside setup, this way you can refer to counter in your own methods and on the template.

Another example of using Composition API would be something like utils methods but it can continuously update values. If you want to keep track of window width when resizing, you can do this:

function useWindowResize() {
  let windowSize = reactive({
    height: 0,
    width: 0
  });

  function getSize() {
    windowSize.height = window.innerHeight;
    windowSize.width = window.innerWidth;
  }

  onMounted(() => {
    getSize();
    window.addEventListener(“resize”, getSize);
  });

  return { windowSize };
}

reactive is another method for keeping tracking changes of object. It is just the renamed version of the current Vue.observable API. Composition API does have access to the component lifecycle as denoted by that onMounted.

I hope the above examples show you how organized and reusable your code can be. I personally don’t think it’s here to replace Options API as it is still very powerful and very easy to pick up for any developers regardless of background. If it has to replace something it’s probably Mixins, which allows you to share code in a Vue way but Composition API does the same in JavaScript way.

Notes:

setup gets called before beforeCreated so you don’t have access to the component by calling this like you would normally do. However setup does accept 2 arguments. The first argument is the props of the current component and the second argument is the Vue context. This way you can access props and you can access the, for example, Vuex store from the context if you’d like. I would imagine this will be easier to do with the release of Vue 3 and all of the other plugins like router and Vuex get updated along with it.

If you’d like to know more about Composition API you can check out the original slides Vue 3 and the Composition API - Vue Toronto by Alex Kyriakidis that I took the pictures from.

Conclusion

Vue 3 may not bring too many new features on the surface but we are still benefitted by these under-the-hood changes as well as the new Composition API that brings new perspective when structuring our codes. You can play with my examples here: vue-composition-api - CodeSandbox. Also if you would like to use Composition API before Vue 3 is out there is a package called @vue/composition-api that you can install.

Cover photo credit goes to unsplash-logoTyler Franta