So What’s New in Vue 2.6?

Lotanna Nwose
Bits and Pieces
Published in
6 min readMar 5, 2019

--

Photo by Adi Goldstein on Unsplash

Just days ago, Vue turned 5 and the team released the newest version 2.6 to celebrate. In this article, we shall take a quick look at the new and shiny things that shipped with this new version and some important changes.

Tip: Share and collaborate on individual Vue components.

Use Bit to encapsulate Vue components with all their dependencies and setup. Build truly modular applications with better code reuse, simpler maintenance and less overhead.

Components with Bit: Easily share across projects as a team

Let’s talk about Slots…

Slots can be seen as a crucial mechanism that helps to compose flexible components in Vue. The Vue team brainstormed a couple of improvements to make on Slots and decided to ship the ones that would not cause breaking changes in this new version.

Firstly, Scoped Slots now have a new syntax. After many documented deliberations, a syntax which best suits scoped slots was chosen and implemented. It is the v-slot syntax, here is a sample of how it works below using named slots:

<template v-slot:header>  <p>Header</p></template><template v-slot:item=”{ data }”>  <h2>{{ data.title }}</h2>  <p>{{ data.text }}</p></template><template v-slot:footer>  <p>Footer</p></template>

The new syntax unifies the usage of normal and scoped slots in a single directive, and enforces more explicit and readable named slots usage. It is also fully compatible with the existing syntax, so it was shipped with the 2.6 version.

Developers familiar with Slots before now can look at the RFC to better understand the rationale behind the new syntax. Those who are not can simply read the updated slots documentation.

Secondly, In a bid to unify normal and scoped slots, due to the higher advantage of scoped slots an optimization has been introduced to make sure that parents scope dependency mutations only affect the parent and would no longer force the child component to update if it uses only scoped slots.

It is important to note that:

  • All slots using the new v-slot syntax are compiled into scoped slots. This means all slots using the new syntax automatically get the performance improvements;
  • All normal slots are now also exposed on this.$scopedSlots as functions. This means users using render functions instead of templates can now always use this.$scopedSlots without worrying what type of slots are being passed in.

Async Error Handling

The built-in error handling mechanism that Vue uses, which involves in-component errorCaptured hooks and the global errorHandler hooks now also catches errors in the v-on handlers. Also, you can now return a Promise from the function if any of your lifecycle hooks or event handlers performs asynchronous operations, so that any uncaught errors from that Promise chain are also sent to your error handlers. It becomes even easier if you are using async/await, since async functions implicitly return Promises:

export default { async mounted() {// if an async error is thrown here, it now will get// caught by errorCaptured and Vue.config.errorHandler   this.posts = await api.getPosts()  } }

Source Range for Compiler Errors

From this new version of Vue, template compile warnings have source range information. As a result, template warnings have code frames to make it easier to spot warnings in templates:

Dynamic Directive Arguments

Directive arguments can now accept dynamic JavaScript expressions. Due to directive arguments being static, currently users would have to resort to argument-less object bindings in order to leverage dynamic keys:

<div v-bind="{ [key]: value }"></div>
<div v-on="{ [event]: handler }"></div>

However, this has a few issues:

  • It’s a lesser known technique that relies on knowledge of the object-based syntax for v-bind/v-on and the existence of computed property keys in JavaScript.
  • It generates less efficient code: an ad-hoc object is allocated and if there are other static bindings on the same element, it has to be dynamically iterated and mixed into the existing data object. The code looks roughly like this:
return h('div', {
on: Object.assign({
click: onClick
}, {
[event]: handler
})
})

Where as with dynamic arguments we can directly generate:

return h('div', {
on: {
click: onClick,
[event]: handler
}
})

In addition, v-slot doesn't have an equivalent object syntax, since it's value is used for declaring the slot scope variable. So without the dynamic argument, the v-slot syntax will not be able to support dynamic slot names. Although this is probably a very rare use case, it would be a pain having to rewrite an entire template into render function just because of this single limitation. Below is the detailed design:

<!-- v-bind with dynamic key -->
<div v-bind:[key]="value"></div>
<!-- v-bind shorthand with dynamic key -->
<div :[key]="value"></div>
<!-- v-on with dynamic event -->
<div v-on:[event]="handler"></div>
<!-- v-on shorthand with dynamic event -->
<div @[event]="handler"></div>
<!-- v-slot with dynamic name -->
<foo>
<template v-slot:[name]>
Hello
</template>
</foo>
<!-- v-slot shorthand with dynamic name -->
<!-- pending #3 -->
<foo>
<template #[name]>
Default slot
</template>
</foo>

Dynamic argument values are expected to be strings. However, it would be convenient if we allow null as a special value that explicitly indicates that the binding should be removed. Any other non-string values are likely mistakes and will trigger a warning.

null as a special value only applies to v-bind and v-on, but not v-slot. This is because v-slot is not a binding and cannot be removed. Custom directives have the liberty of deciding how to handle non-string arguments, but are expected to follow the convention when it applies.

Explicit Creation of Standalone Reactive Objects

The new version of Vue ships with a new global API to explicitly create standalone reactive objects:

const reactiveState = Vue.Observable({  count: 0})

The resulting object can be used directly in computed properties or render functions, and will trigger appropriate updates when mutated.

Data Pre-fetching during Server Side Rendering

Instead of just route-level elements, the new serverPrefetch hook allows any component to pre-fetch data during server side rendering. This would clearly create a platform for more flexible usage, reducing the coupling between data fetching and router. The Nuxt team as well as Vue-Apollo team are already working on using this simplify implementations in their frameworks.

ES Module Build for Direct Import

In the past, our ES Module build was primarily intended for use with bundlers. These builds contain usage of environment variables that are meant to be replaced at compile time. The new version of Vue now also provides an ES Module build that are intended for direct in-browser usage:

<script type=”module”> import Vue from ‘https://unpkg.com/vue/dist/vue.esm.browser.js'  new Vue({ // … })</script>

⚠️Changes to Note

Reverting nextTick to Microtask

In 2.5.0 version, an internal adjustment was made that caused nextTickto use Macrotasks instead of Microtasks to queue updates if the update was triggered in a v-on event handler. This was originally intended to fix some browser edge cases, but has in turn led to a number of other issues. In this new version 2.6 we have found a simpler fix for the original issue, which allows us to revert nextTick to consistently use Microtasks in all cases.

Functions on this.$scopedSlots now always return Arrays

In render functions, scoped slots are exposed on this.$scopedSlots as functions. Up until now, calling a scoped slot function can return a single VNode or an Array of VNodes based on what the parent component is passing in. This was honestly an oversight as it makes the return value type indeterministic and can lead to unintended edge cases. In the new version 2.6, scoped slot functions are now guaranteed to return either an Array of VNodes or undefined. This may affect some existing code if it is not properly checking for possible Array return values. This change only affects render function users.

Conclusion

We have seen all the changes and the improvements that ships with this new version of Vue. As we look forward expectantly for Version 3, we cannot help but admire the effort the Vue team always put into simplifying the Vue experience. What is your favorite new feature?

--

--

Helping Startups with Webhooks management at Convoy so they can focus on their core product offerings. Twitter:@viclotana