Some of My Favourite Features in Vue 3 (Incl. 3.2)

Some of My Favourite Features in Vue 3 (Incl. 3.2)

Vue 3 is the next major iteration of the popular framework. It has brought several notable features to the table to improve on performance and DX.

In this article, I’ll highlight some of the major features that I personally found fascinating while digging deeper. Without further ado, let’s get to them!

Tree-shakable Global & Internal APIs

Resources: RFC, Vue.js documentation

Due to how the code was written in Vue 2, mainstream bundlers such as Webpack were unable to take advantage of their tree-shaking capability. Therefore, although projects didn’t make use of certain APIs, they were always included in the final bundle.

By contrast, Vue 3 has been rewritten from ground-up with this in mind. For instance, from now on, the nextTick() method can only be accessed as a named export:

import { nextTick } from 'vue’;

nextTick(() => {
  // …
});

By making Vue 3 tree-shakable, unused APIs are stripped off the final bundle. In addition, it also opens up the possibility to release more and more optional features in the future, without worrying Vue's size overhead.

Composition API & <script setup> Syntax

Resources: RFC (#1, #2), Vue.js documentation (#1, #2)

One of the most significant and anticipated changes of Vue 3 was the Composition API. It allows developers to collocate features logically leading to more readable code and giving developers more flexibility when it comes to developing applications.

The entry point for composition API is the new setup() component option:

  1. It’s executed before the component is created (kinda serves as a replacement for the created() lifecycle hook) and once the props are resolved.
  2. Everything that gets returned from setup() will be exposed to the rest of the component.
<script>
import { ref } from 'vue';

const useCounter = () => {
  const counter = ref(0);

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

  return {
    counter,
    increment,
  };
};

export default {
  setup() {
    const { counter, increment } = useCounter();

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

As you can see, exposing all the bindings to the render context is quite verbose: you have to return counter and increment twice (from both useCounter and setup). Not only that, but oftentimes setup() is the only option that's being used resulting in boilerplate code.

To address these, Vue 3.2 shipped the <script setup> syntax:

<script setup>
import useCounter from './useCounter';

const { counter, increment } = useCounter();
</script>

It's a syntactical sugar that runs in the context of setup() and exposes everything to the template (even components!) without exporting or referring to them explicitly.

Note that there's a lot more to Composition API that's beyond the scope of this article. Consult with the RFCs and official documentation to dive deeper.

Fragments

Resources: Vue.js documentation

This one a minor, yet long-awaited change to authoring components. You’re no longer required to wrap multiple elements (e.g. in a <div />) solely to silence the error:

<template>
  <Header />
  <Main />
  <Footer />
</template>

There’s one caveat: since there are multiple root nodes, Vue’s automatic attribute behaviour is no longer capable of attaching attributes to the root node.

Instead, they should be bound explicitly to the proper element:

<template>
  <Header />
  <Main v-bind=“$attrs” />
  <Footer />
</template>

Conclusion

This article is just the tip of the iceberg!

On the one hand, I deliberately didn't explain the ins and outs of my highlights above - it would go against my intent, to keep it concise.

On the other hand, the team has introduced many more features and refinements to the framework. Keep an eye on Vue if it's got you curious!

Thanks for reading! If you have anything to add or wanna connect, feel free to hit me up on Twitter or leave a comment down below.