DEV Community

Jingtian Zhang
Jingtian Zhang

Posted on

Vue3 Composition API and New Features

The combination of Vue3.0 and Typescript is getting more and more trending, let's check how to build single file components using them and understand how it works.

Composition API

One of the most important changes in Vue3.0 is the Composition API,Vue3.0 is backwardly compatible with the Options API, but using the Composition API grants you more power for code sharing.

you can find a detailed cheatsheet about composition API here

Going through the cheetsheet we can have a basic understanding of composition API:

  1. replacing mixins
  2. better code sharing across components

The composition API gets rid of mixins, using a mixin in Vue2.0 would be like:

import Mixin from "./Mixin.js";

export default {
  mixins: [Mixin],
  data: () => ({
    data1: null
  }),
  methods: {
    method1 () { ... }
  }
}
Enter fullscreen mode Exit fullscreen mode

back in 2016 Dan Abramov wrote an article called Mixins Considered Harmful, the harm he mentioned was basically using mixin is an anti-pattern and would not recommend it. The same drawback applies to both React and Vue:

  • naming collisions
    • names used in mixins could confront with the one in the file that uses it
  • implicit dependencies
    • mixins can use methods or properties in the file too, which causes confusion, especially when refactoring code developer may omit details in mixins and causes confusion

in composition API, rather than defining a component's functionality (state, methods, computed, etc.) as an object property, we define them as JS variables that get returned from a new setup function

// define reactive variable that functions pretty much the same as a data variable 
import {ref, computed } from "vue";

export default {
  setup(){
    const count = ref(0);
    const double = computed(() => count.value * 2)
    function increment(){
      count.value++;
    }
    return {
      count,
      double,
      increment
    }
}
Enter fullscreen mode Exit fullscreen mode

while we can definitely extract the common logic to a single file

// useCounter.js
import { ref, computed } from "vue";

export default function () {
  const count = ref(0);
  const double = computed(() => count.value * 2)
  function increment() {
    count.value++;
  }
  return {
    count,
    double,
    increment
  }
}
Enter fullscreen mode Exit fullscreen mode

and the code can be reused in another component by importing it.

// MyComponent.js
import useCounter from "./useCounter.js";

export default {
  setup() {
    const { count, double, increment } = useCounter();
    return {
      count,
      double,
      increment
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

notice here we need to use states or methods from logic by importing them explicitly, thus solving the naming collision issue

Top comments (0)