Menu

Poland

GRANDMETRIC Sp. z o.o.
ul. Metalowa 5, 60-118 Poznań, Poland
NIP 7792433527
+48 61 271 04 43
info@grandmetric.com

Sweden

Drottninggatan 86
111 36 Stockholm
+46 762 041 514
info@grandmetric.com

UK

Grandmetric LTD
Office 584b
182-184 High Street North
London
E6 2JA
+44 20 3321 5276
info@grandmetric.com

US Region

Grandmetric LLC
Lewes DE 19958
16192 Coastal Hwy USA
EIN: 98-1615498
+1 302 691 94 10
info@grandmetric.com

  • en
  • pl
  • se
  • What’s new in Vue 3

    What’s new in Vue 3

    Date: 03.08.2020



    Vue 3 will be released soon with many interesting improvements. In this article, we’ll take a look at new features with code examples.

    Vue 3 applications are going to be around 50% smaller (10kB) than Vue 2, better structured and more maintainable. Also Virtual DOM got rewritten for better performance. Probably the most exciting feature of version 3 is Composition API, so let me start by introducing it.

    Composition API

    Introduction

    Composition API is optional set of function-based APIs that allows creating components in a way that simplifies code organization and logic reuse.

    Basics

    <template>
      <h1>Hello Vue 3!</h1>
      <button @click="inc">Clicked {{ count }} times.</button>
    </template>
    
    <script>
    import { ref } from 'vue'
    
    export default {
      setup() {
        const count = ref(0)
        const inc = () => {
          count.value++
        }
    
        return {
          count,
          inc
        }
      }
    }
    </script>

    Setup

    Setup option is a function in which we create functions or properties for further use in the template. This function accepts two arguments: props and context and is executed before the component is created. Props are reactive – you can’t use destructuring on them, because they will lose reactivity. The second argument – context – is a JavaScript object that exposes three-component properties: attrs, slots and emit. Everything that we return from setup will be exposed to the rest of our component.

    Reactive variables

    Ref function makes any primitive data type reactive (String, Number, Boolean etc.) – creates a reactive reference to our value.

    Reactive function makes given object reactive, it affects all nested properties.

    Lifecycle hooks

    In Composition API we register lifecycle hooks in setup function, but prefixed with ‘on’ (i.e. onMounted) setup function replaces beforeCreate and created methods. ‘destroyed‘ and ‘beforeDestroy‘ maps to ‘onUnmounted‘ and ‘onBeforeUnmount’. The rest of lifecycle methods naming hasn’t changed.

    Computed properties

    To use computed properties in Composition API, you’ll need to import computed function. This function takes getter function as an argument and returns a reactive reference to the output of the input function.

    import { ref, computed } from 'vue'
    
    const counter = ref(0)
    const counterDoubled = computed(() => counter.value * 2)
    
    counter.value++
    console.log(counter.value) // 1
    console.log(counterDoubled.value) // 2
    

    Code reuse

    In Vue 2, mixins were a standard way of sharing functionalities between components; however, they had a few significant downsides, including naming collisions or unclear relationships on how they interacted. What’s more, it was not clear what functionality we were importing from a mixin. Let’s see how to replace mixins with Composition API.

    const textUtilsMixin = {
      methods: {
        fullName(firstName, lastName) {
          return `${firstName} {lastName}`;
        }
      }
    }
    
    // define a component that uses this mixin
    const Component = Vue.extend({
      mixins: [myMixin]
    })
    
    function useTextUtils() {
      const fullName =  (firstName, lastName) => {
        return `${firstName} ${lastName}`;
      }
      return { fullName }
    }
    
    export default {
      setup() {
        const { fullName } = useTextUtils();
        return { increment }
      }
    }

    Improved Typescript support

    As you can see in previous examples, the Composition API is heavily based on functions, which means that adding Typescript to our components is easier.

    State variables in style tag

    Note: At the time of writing this article this feature is experimental.
    Vue 3 makes it possible to inject component-state-driven CSS variables into Single File Component style. It allows dynamic updating of styles based on component state.
    This alternative to inline styles and dynamic classes is very promising! Style vars uses CSS variables under the hood, so you need to be aware of the browser support range.
    Take a look at the example:

    <template>
      <div class="text">hello</div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          color: 'red'
        }
      }
    }
    </script>
    
    <style scoped vars="{ color }">
    .text {
      color: var(--color);  /* Scoped (local) variable */
      font-size: var(--global:fontSize)  /* Global CSS variable */;
    }
    </style>

    Teleport (portal) – new in Vue 3

    While Vue component-oriented nature helps us build small, tree-structured reusable components, there is sometimes a need to move elements somewhere else in the DOM.

    For example, this need arises when we need to create a custom modal accessible in single components, but rendered in the bottom of the body element. Up until now, we had to use a third-party package called portal-vue to do this. Now we can use the built-in Teleport component, that’s new in Vue 3.

    <body>
      <div id="app">
        <div>
          <teleport to="#endofbody">
            <div class="modal">
              Modal content
            </div>
          </teleport>
        </div>
      </div>
      <div id="endofbody"></div>
    </body>

    Elements from inside of teleport component will render inside targeted div.

    Suspense

    Suspense is a built-in component that we can use to provide fallback content while some asynchronous work is happening. For example, it is useful when you need to fetch data from the server and show a loading spinner.

    <template>
      <Suspense>
        <template #default>
          <div v-for="item in articleList" :key="item.id">
            <article>
              <h2>{{ item.title }}</h2>
              <p>{{ item.body }}</p>
            </article>
          </div>
        </template>
        <template #fallback>
          Articles loading...
        </template>
      </Suspense>
    </template>
    <script>
    import axios from 'axios'
    export default {
      async setup() {
        const { data: articleList } = await axios.get('https://jsonplaceholder.typicode.com/posts')
        return {
          articleList
        }
      }
    }
    </script>

    Multiple root nodes in templates

    In Vue 2 the following code would throw an error:

    <template>
      <div>...</div>
      <div>...</div>
    </template>

    Now it is a valid syntax! You don’t have to create wrappers anymore. Just put content in it — very convenient change.

    Conclusion

    What’s new in Vue 3 will surely change the way we write components, thanks to the Composition API. Other smaller improvements will help us develop faster and with better performance. I’m sure this version will further strengthen Vue’s position in web development.

    I also encourage you to read my post about VueJS unit testing config with examples. Unit tests will make your migration to Vue 3 easier!

    Tags:

    Author

    Adam Skowronek

    Adam Skowronek is currently studying computer science at the Adam Mickiewicz University in Poznań. His interests include web development, software engineering, Linux and backend development.

    Leave a Reply

    Your email address will not be published. Required fields are marked *


    Grandmetric