Vue 3
What's new in
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
Vue now has a much bigger ecosystem to carry with it
also: COVID happened
vuejs.org still links to v2 docs
Vue 3 is vue@next on NPM
vue-devtools for v3 are still in beta
(or almost time)
another framework migration is coming
Vue 3 uses named imports instead of global properties
These are tree-shakeable → only loaded if your app needs it
Vue 2
Vue 3
Breaking change: app declaration changed to avoid a global API that affects all instances of Vue apps in the page
Vue 2
Vue 3
<!-- 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
Vue automatically refreshes the UI when data is mutated
That's reactivity
In Vue 2, it was done using 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
}
}
→ Vue overrides every mutative method to insert its observers
users.push(newUser)
results.sort(selectedSorting)
todos.splice(deletedTodoIndex, 1)
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
(the big ones at least)
<template>
<p>several</p>
<p>root nodes</p>
<p>per component</p>
<p>are now supported !</p>
</template>
<template>
<teleport to="body">
<div class="modal">
I'm a teleported modal!
(My parent is "body")
</div>
</teleport>
</template>
<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
export default {
name: "KlaxonComponent",
emits: ["beep"]
}
document the events emitted by your components
and get autocompletion for free on $emit and v-on
<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:
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>
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>
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
<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>
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.
<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 !
TLDR: smaller, faster, better DX
🧱
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:
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:
coming to stable channel
very soon
will support both
Vue 2 and Vue 3
(autodetected)
+ many new features
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