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

 

See notes

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

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

 

vueuse.org 

pikax.me/vue-composable

 

 

😐 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

sylvain.polletvillard@worldline.com

Made with Slides.com