preface

On September 18, Vue 3.0 was officially released. The Composition API is one of the highlights of the new release. This article will use a small demo to briefly introduce the main features and usage of the Composition API. In the meantime, we’ll use Vite, a new build tool released by the Vue team, as the build tool for this little demo.

What is the Composition API?

The official documentation for Vue 3 is now available at v3.vuejs.org (no Chinese version is available yet). Find the Composition API in the documentation for a detailed description of the API. As we know from the official documentation, the Composition API is designed to address the maintainability, flexibility, and reusability of larger Vue components. A traditional Vue component divides the component into props, Components, data, methods, computed, Watch, and multiple declaration cycle hooks. The common energy of each logic of the component is also scattered in these multiple parts. When the component has a certain scale, the code logic will be fragmented, which greatly affects the maintainability of the code.

To solve this problem, the Vue team came up with the idea of organizing the code in large components together in logical relationships, which led to the creation of the Composition API. Using the Composition API may be a better way to avoid problems when a component does the following:

  • A piece of code can be reused in multiple components, and you want to use other methods to replace mixins or slots
  • Ensure type safety (especially when using TypeScript)

Set up the demo

First we initialize the project with the Vite build command vue3-composition-api-demo (by the way, Vite can also be used to build react projects)

Initialize the project
npm init vite-app vue3-composition-api-demo
# enter directory
cd vue3-composition-api-demo
# install dependencies
npm install
# Run the project
npm run dev
Copy the code

Development environment projects are really much faster to build than WebPack, thanks to the native ES Module support. A similar build tool, Snowpack, is available for those interested.

Basic use of the Composition API

The Composition API is available out of the box in Vue 3. If you want to use the Composition API in Vue 2, you can add the @vue/ composition-API plug-in to your project.

First we write some template code:

<template>
  <div>
    <p>Spaces left: {{ spacesLeft }} out of {{ capacity }}</p>
    <h2>Attending</h2>
    <div>
      <button @click="increaseCapacity">Increase Capacity</button>
    </div>
    <div>
      <button @click="addAttending">addAttending</button>
    </div>
    <div>
      <button @click="sort">sort</button>
    </div>
    <! -- Use vue's transition animation component to demonstrate, too troublesome students can also not use.
    <transition-group name="flip-list" tag="ul" :style="{width: '200px', margin: '20px auto'}">
      <li v-for="item in attending" :key="`Attending${item}`">
        {{ item }}
      </li>
    </transition-group>
  </div>
</template>
Copy the code

Two data variables capacity and INTERACTION, a computed property spacesLeft and several related functions are used in the Vue template.

We then define them in script tags. We’ll implement these functions in two ways, using the Setup method.

Writing a

// Introduce ref and computed
import { ref, computed } from "vue"
export default {
  setup() {
    const capacity = ref(4)
    const attending = ref(["Tim"."Bob"."Joe"])
    // How to declare attributes computed
    const spacesLeft = computed(() = > {
      // Note that reactive data declared by ref needs to be retrieved by.value
      return capacity.value - attending.value.length
    })
    // Declare methods instead of methods
    function increaseCapacity () {
      capacity.value++
    }
    function sort () {
      attending.value = lodash.shuffle(attending.value)
    }
    function addAttending () {
      attending.value.push(randomName(lodash.random(3.7)))}// Expose the above variables and methods through an object
    return {
      capacity,
      attending,
      spacesLeft,
      increaseCapacity
    }
  }
}
Copy the code

Where ref() receives a value as an input parameter, the entry of the basic type will be wrapped in an object (such as Capacity), and the response will be implemented by proxy (much like Vue 3). Computed attributes are declared using computed() methods (all replaced with functional declarations). Note that in computed, we need to call capacity. Value and loth. value to get the value of the data. Finally, all variables and methods used in the template are exposed via return. Let’s look at the second way.

Write two

import { reactive, computed, toRefs } from "vue"
export default {
// Add the variables you want to use to the event properties
  setup(props, context) {
    const event = reactive({
      capacity: 4.attending: ['Tim'.'Bob'.'Joe'].spacesLeft: computed(() = > { return event.capacity - event.attending.length })
    })
    // The method declaration method remains the same
    function increaseCapacity () {
      event.capacity++
    }
    function sort () {
      event.attending = lodash.shuffle(event.attending)
    }
    function addAttending () {
      event.attending.push(randomName(lodash.random(3.7)))}// toRefs()
    return{... toRefs(event), increaseCapacity, addAttending, sort} } }Copy the code

The change is toRefs(). The toRefs() method takes a Reactive instance as an input and returns a Reactive object. Inside the setup() function, fetch the value of the variable directly from the event property, without adding an additional.value. There are slight differences in usage scenarios between the two. Personally, I prefer the second method, where return is more concise and elegant 👍.

Finally, the page should look something like this:

The setup method

Let’s look at the setup() method.

setup(props, context) {
  // Attributes (Non-reactive object)
  console.log(context.attrs)

  // Slots (Non-reactive object)
  console.log(context.slots)

  // Emit Events (Method)
  console.log(context.emit)
}
Copy the code

The setup() method takes two arguments, the first of which is, as the name implies, props of Vue. Setup () doesn’t have a VUE instance yet, so you don’t have data, computed, or methods in the setup() function, so you need the second context parameter to get the vue instance data, which includes attrs, slots, and EMIT.

Setup life cycle hooks

Setup () has corresponding VUE lifecycle hooks inside for developers to use. Official documents have detailed lists.

Let’s print the new version and the new version for comparison.

import {
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onUnmounted
} from "vue"

function printLifeCycle () {
  onBeforeMount(() = > {console.log('onBeforeMount')})
  onBeforeUpdate(() = > {console.log('onBeforeUpdate')})
  onMounted(() = > {console.log('onMounted')})
  onUpdated(() = > {console.log('onUpdated')})
  onUnmounted(() = > {console.log('onUnmounted')})}export default {
  // Setup internal lifecycle hooks
  setup(props, context) {
    printLifeCycle()
  },
  // old life cycle hooks
  beforeCreate() {
    console.log('beforeCreate')},created() {
    console.log('created')},beforeMount() {
    console.log('beforeMount')},mounted() {
    console.log('mounted')},beforeUpdate() {
    console.log('beforeUpdate')},updated() {
    console.log('updated')}}Copy the code

The hooks execution inside setup() precedes the old hooks on vue instances. The printing order is as follows:

Easter Egg – Vite introduces third party libraries

Careful students should have noticed that I used Shuffle and Random of Lodash in the demo. Introducing a dependency in Vite that does not use ES Module will cause an error that the dependency cannot be found. Note that the dependency was added under the optimize configuration in viet.config.js:

module.exports = {
  optimizeDeps: {
    include: ["lodash"]}}Copy the code

When introducing lodash, note that this will result in an error:

import { random, shuffle } from 'lodash'
Copy the code

This also generates an error:

import random from 'lodash/random'
import shuffle from 'lodash/shuffle'
Copy the code

So for now we can only introduce lodash in its entirety:

import lodash from 'lodash'
Copy the code

The ES Module is a small hole, related questions can refer to this blog vite try and get Started.