Vue 3
What's new in
If you never heard of Vue before
it's a JavaScript framework
used to link data to UI
very popular
easy to start with
with a rich ecosystem
ideal for Single Page Apps
with similar DX to Angular
but smaller and more flexible
Vue.js version | Release Date |
---|---|
3.2 (Current) | August 5, 2021 |
3.0 | September 18, 2020 |
2.6 | February 4, 2019 |
2.0 | September 30, 2016 |
1.0 | October 27, 2015 |
1 year between Vue 1 and Vue 2
4 years between Vue 2 and Vue 3
Vue 3 should last longer than that
It's been a year !
Why talk about it now ?
Vue now has a much bigger ecosystem to carry with it
also: COVID happened
The "Big Switch"
did not happen yet
-
vuejs.org still links to v2 docs
-
Vue 3 is vue@next on NPM
-
vue-devtools for v3 are still in beta
...but should happen
very soon 🐸
Checklist before considering promoting Vue 3
- are devtools ready for Vue 3 ?
- is it well integrated in IDE ?
- is vue-router updated ?
- and VueX ?
- what about testing libraries ?
- and the bigger UI frameworks,
Vuetify, Quasar, etc ? - do we have training material
for Vue 3 ? - ...
I think it's time !
(or almost time)
Brace yourselves
another framework migration is coming
- There is no rush to migrate, Vue 2 is still great
- Vue upgrades have always been easy
- Most of the API remains stable
(definitely not like Angular.js → Angular 2) - There's a migration build
+ tons of guides
- The complicated part will be the dependencies
No worries !
- Smaller, faster, more modular
- More Typescript-friendly
- Easier to scale with Composition API
- Reactivity is less magic and more explicit
So, why Vue 3 ?
the (few)
breaking changes
🪓
Vue 3 uses named imports instead of global properties
These are tree-shakeable → only loaded if your app needs it
Vue 2
Vue 3
Global API are gone !
Breaking change: app declaration changed to avoid a global API that affects all instances of Vue apps in the page
Vue 2
Vue 3
Global API are gone !
Filters are gone !
<!-- Vue 2 -->
<span class="name">{{ user.name | capitalize }}</span>
<!-- Vue 3 (and Vue 2 as well) -->
<span class="name">{{ capitalize(user.name) }}</span>
Filters were basically reversed method calls
a custom Vue-specific syntax
that did not bring much on the table
Use methods instead
Reactivity changes in Vue 3
Vue automatically refreshes the UI when data is mutated
That's reactivity
In Vue 2, it was done using getters/setters
getters/setters
let _name = "joe";
const user = {
get name() {
console.log("accès en lecture à la propriété")
return _name
},
set name(value) {
console.log("accès en écriture à la propriété")
_name = value
}
}
getters/setters
the limitations
- all mutated properties have to be known beforehand
so that Vue set up the getters/setters on them
→ Vue requires you to declare every data you use
- data can also be mutated with mutative methods:
→ Vue overrides every mutative method to insert its observers
users.push(newUser)
results.sort(selectedSorting)
todos.splice(deletedTodoIndex, 1)
In Vue 3,
Proxies are used instead
const _user = { name: "joe" }
const user = new Proxy(_user, {
get(obj, key) {
console.log(`accès en lecture à la propriété ${key}`)
return Reflect.get(obj, key)
},
set (obj, key, value) {
console.log(`accès en écriture à la propriété ${key}
avec la valeur ${value}`)
return Reflect.set(obj, key, value)
}
})
Proxies can also catch new properties assignment and mutative method calls
No more limitations 🎉
The switch from getters/setters to proxies
simplifies a lot the reactivity system
Problem: they are not supported by IE
Initial plan to add a compatibility layer for IE11 on Vue 3 has changed
Instead, the team wants to port as much new features as possible to Vue 2
Vue 3 dropped support for Internet Explorer 11
that's it for the breaking changes
(the big ones at least)
now the
new cool stuff
😎
multi-root templates
<template>
<p>several</p>
<p>root nodes</p>
<p>per component</p>
<p>are now supported !</p>
</template>
<Teleport>
<template>
<teleport to="body">
<div class="modal">
I'm a teleported modal!
(My parent is "body")
</div>
</teleport>
</template>
<Suspense>
<router-view v-slot="{ Component }">
<template v-if="Component">
<transition mode="out-in">
<keep-alive>
<suspense>
<component :is="Component"></component>
<template #fallback>
Loading...
</template>
</suspense>
</keep-alive>
</transition>
</template>
</router-view>
a better way
to manage loading states
on components
emits option
export default {
name: "KlaxonComponent",
emits: ["beep"]
}
document the events emitted by your components
and get autocompletion for free on $emit and v-on
:global, :slotted, :deep
CSS selectors
<style scoped>
:global(.a){
/* will affect every .a element in the document */
}
:slotted(.b){
/* will affect elements .b in slot content */
}
:deep(.c) {
/* will affect elements .c in child components */
}
</style>
the big new thing:
Composition API
An alternative function-based API
for declaring components with
flexible composition of logic.
What's wrong with the Options API ?
export default {
components: { RepositoriesList },
props: ['user'],
data () {
return {
repositories: [],
filters: { ... },
searchQuery: ''
}
},
computed: {
filteredRepositories () { ... },
repositoriesMatchingSearchQuery () { ... },
},
watch: {
user: 'getUserRepositories'
},
methods: {
getUserRepositories () {
// using `this.user` to fetch user repositories
},
updateFilters () { ... },
},
mounted () {
this.getUserRepositories()
}
}
Elements are sorted by type,
not by purpose
Logic ends up scattered on large components
Source: Logical concerns in a file explorer component
let you declare everything in any order*
*preferably an order that makes sense !
Every var here is data exposed in template
Every function is a method exposed in template
<script setup>
<script setup>
const who = 'world' // ← data
function greet() { // ← method
alert("Hello !")
}
</script>
<template>
<div @click="greet">Hello {{ who }}</div>
</template>
every import is exposed too
works with methods, data, components...
<script setup>
<script setup>
import MyComponent from "./MyComponent.vue"
import capitalize from "./helpers.js"
</script>
<template>
<MyComponent>
{{ capitalize("Hello") }}
</MyComponent>
</template>
reactivity is now opt-in and explicit in <script setup>
use ref for primitives and reactive for objects
ref & reactive
<template>
<ul>
<li v-for="todo in todos" :key="todo">{{todo}}</li>
</ul>
<input type="text" v-model="newTodo" />
<button @click="addTodo">Add new task</button>
</template>
<script setup>
import { ref, reactive } from "vue"
const todos = reactive(["do laundry"])
const newTodo = ref("something else")
function addTodo(){
todos.push(newTodo.value)
}
</script>
every option in the Options API has a functional equivalent in the Composition API
<script setup>
<script setup>
import { defineProps, computed, watch, onMounted } from "vue"
const props = defineProps({ id: Number })
const name = computed(() => users[props.id].name)
watch(props.id, (newId) => fetchTodos(newId))
onMounted(() => fetchTodos(props.id))
</script>
Composition API is now the best solution for logic reusability and managing the scaling of Vue projects
Mixins are not deprecated (yet),
but it makes sense to replace them with setup imports.
Composition API > Mixins
<script setup>
import * as common from "./common.js"
</script>
<script>
import commonMixin from "./common.js"
export default {
mixins: [commonMixin],
...,
}
</script>
The <script setup> imports & auto-expose lead to a new pattern for composition helpers: the use pattern
😐 Options API is still there if you don't want to switch !
use pattern
that's all for Vue 3 core news !
TLDR: smaller, faster, better DX
now, a short tour
of ecosystem updates
🧱
Vue-router 4
v3 is for Vue 2, v4 is for Vue 3 😪
Most of Vue Router API remains unchanged
Migration guide for the few breaking changes:
next.router.vuejs.org/guide/migration
New Features:
- Dynamic Routing
- Composition API
VueX 4
v3 is for Vue 2, v4 is for Vue 3 😪
Most of VueX API remains unchanged
Migration guide for the few breaking changes:
next.vuex.vuejs.org/guide/migrating-to-4-0-from-3-x.html
New Features:
- Composition API
vue-devtools 6
coming to stable channel
very soon
will support both
Vue 2 and Vue 3
(autodetected)
+ many new features
Should I upgrade to Vue 3 ?
- do you need to support IE11 ?
- do you need a dependency not yet updated for Vue 3 ?
- otherwise, YES you should !
→ no rush though !
Thanks !
I give a 2-day internal training session
to Vue.js, both v2 and v3.
Also available for any support/question,
be it Vue or something else javascriptish
What's new in Vue 3 ?
By sylvainpv
What's new in Vue 3 ?
- 1,179