Long-awaited version 3 of the popular Vue framework is finally released (after 6 months in beta and release candidate), packed with interesting new things for Vue developers.
Named “One Piece” and hosted in a separate repo, vue-next, for a period of time (to avoid being confused with 2.x and also not to be picked by npm install as @latest), the new version promises increased performance, smaller bundle size, and interesting new features to at least intriguing us for discovering more.
Let’s take a first look at what’s new to decide if we go all-in with the new version or wait for the moment.
Vue 3 introduces the Composition API, which addresses the biggest problem (*personal opinion) of Vue, the use of mixins. Mixins are a good way of abstracting code to make it more reusable, but they have some flaws: they hide the code – at some point, a method defined in the mixin is called into the component, but that method is nowhere to be found inside the component. So you start digging up, losing time tracing the method to debug. In the extreme case of mixins nested in other mixins, this job increases in complexity. Other downsides are possible namespace clash (when you define a method in your component with the same name as one in the mixin) and have side effects hard to trace and the possibility of adding too much code in the mixin that is only partly used in a component at the time, this way incorporating to much bloat in components. The new Composition API in Vue 3 is giving us a new way of defining reusable code in Composables, which are more concise and clear as structure, then import these building blocks to construct our components.
Vue 3 promises to be faster and to have a smaller bundle size. On Vue 2, one way of gaining performance was to transform stateful components in functional ones when you have a lot of them in the DOM, to save lost time on register/unregister when re-rendering. On Vue 3, the functional prop was taken out from components (only render functions from now on), but the difference in performance between functional components and stateful ones became negligible, so we are advised to use only stateful components (for the part of us that does not like to use render functions).
Another point that will increase the performance of a Vue 3 application is compiler-informed Virtual DOM. This means that at compile-time, the resulting render functions that go into the bundle are flagged when they contain runtime dynamically changing elements. This way, at runtime, the Virtual DOM is aware of the elements to look for changes and not waste time on watching static ones.
In Vue 3, tree-shaking of Vue internals has been added at compile time. This is a step further in the “progressive framework” approach, allowing us to transport in the bundle only the Vue internals we are actually using. More than this, we have the possibility to manually flag the compiler for the parts it can’t detect automatically for tree-shake.
The new proxy-based reactivity system will speed even further the runtime of our application (check the MDN docs on proxies to find more on this interesting topic).
Some other interesting new features can be found in Vue 3.
The new <teleport> component allows us to render a part of the component template somewhere else in the DOM than the containing component place. Very useful for triggering a modal or a spinner from inside of a component to a more generic point in the DOM (e.g. <body>). Or, when you have a hamburger button on a mobile collapsed layout header to be able to trigger the navigation list outside that layout component.
<suspense> is another component that acts as a wrapper for our component, allowing it to have an alternate template displayed until async operations are executed. Simply put, it allows us to show a loading template until the actual template is loaded and hydrated.
The new Vue 3 now supports multiple elements in the root of the <template>. This means no more wrapping all the elements in the template in one big <div> to avoid an error. Nice addition!!!
<v-model> has a new API in the form of <component v-model:key=”binding”>. This allows us to pass multiple v-model binding for the same component. Multiple two-way bindings on one component. Nice!!!
Filters have been removed from Vue 3 (these are the pipes for those coming, like myself, from the Angular world). From now on, to avoid confusion, only direct method binding {{ convertToCelsius (degrees) }}.
Some additions have been made to the Single File Components syntax. One is the new <script setup>, which is a shorthand to use instead of returning the setup function for the Composition API. The other interesting one is <style vars>, which allows us to pass CSS variables to the style sheet and this way to control dynamically the style at runtime.
For those of you wanting to tweak the framework or even to use parts of Vue to build their own framework, new modular internals of Vue 3 are here, replacing the monolith core of Vue from former versions.
Lastly, the wide use of TypeScript in Vue 3 allows you to have on the fly type inference in your component when you instantiate a variable. And if you already declare the type of your props, you’re already there.
The last thing to mention is that Vue 3 will stay on @next tag until somewhere the end of 2020 when a coordinated switch of all components to @latest will be made. Also, a minor release of Vue 2.7 is scheduled for Q1/2021, having all the 3.x backward compatible features included and the migration build for 3.x. At that point, 2.7 will enter LTS for 18 months.
Now that we have a clearer picture of what Vue 3 brings to the table, we ask ourselves what to do next? And as usual, there are few different answers to this question, depending on the current state of your application.
If you have a small application(s) that work fine and have no benefit from using the above-mentioned changes, just keep them on 2.x.
If you start a new application with Vue, start it directly on Vue 3, this way you have all the new benefits of the framework and your application is future proof for what’s to come for a longer period of time. The only drawback in this situation is that some of the submodules are not yet on stable releases, but I think most are stable enough (beta or RC) to be usable and soon stable.
If your application is a complex one and you were already thinking of some refactoring, could be the time to start architecting for the transition to Vue 3 and by the time you figure it out, hopefully, all the pieces will be in place for a fast migration and the benefits brought by Vue 3.
Else, if you have a complex application that is working fine now, you will want to wait a bit for the migration build to be in place and do a two-step migration to Vue 3 using this build as an intermediary step.
Either way, hope you will enjoy the new iteration of the framework and happy coding!