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.
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:
v-slot
syntax are compiled into scoped slots. This means all slots using the new syntax automatically get the performance improvements;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.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()
}
}
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:
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:
v-bind
/v-on
and the existence of computed property keys in JavaScript.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.
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.
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.
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>
In 2.5.0 version, an internal adjustment was made that caused nextTick
to 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.
this.$scopedSlots
now always return ArraysIn 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.
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?
☞ Vue Authentication And Route Handling Using Vue-router
☞ Vuejs 2 Authentication Tutorial
☞ Comparing the React and Vue Ecosystems with a Real-World SPA
☞ Javascript and Functional Programming: An Introduction
☞ ES5 to ESNext — here’s every feature added to JavaScript since 2015
☞ Build a Simple CRUD App with Spring Boot and Vue.js
☞ Build a Basic CRUD App with Laravel and Vue
☞ Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)
☞ Nuxt.js - Vue.js on Steroids
☞ The Complete JavaScript Course 2018: Build Real Projects!
Originally published by Nwose Lotanna at https://blog.bitsrc.io
#vue-js #javascript #web-development