SoFunction
Updated on 2025-04-12

A brief analysis of the assembly API of Vue 3.0 (I)

(I) Responsive data

1. Simple example

Starting with the simplest data binding, in Vue 2.0, we bind a data to the specified location of the template like this:

Returns a data object to bind in the data constructor for the component creation parameter, with onenowThe fields will be rendered into the template.app > pInside.

<template>
  <div class="app">
    <h1>Hello world!</h1>
    <p>Now is: {{()}}</p>
  </div>
</template>

<script>
// Vue 2.0
export default {
  data() {
    return {
      now: new Date(),
    };
  },
};
</script>

If implemented using Vue3's assembly API, it's like this:

// Vue 3.0
export default {
  setup() {
    return {
      now: new Date(),
    };
  },
};

2. Update data

Strange, it seems like there is no difference, justdataChange tosetupIs it?

No, if we make a small change to this DEMO now and refresh the time every second, we will probably achieve this using Vue2:

// Vue 2.0
export default {
  data() {
    return {
      now: new Date(),
    };
  },
  mounted() {
    setInterval(() =>  = new Date(), 1000);
  },
};

The equivalent implementation of Vue3 is:

// Vue 3.0
import { ref, onMounted } from 'vue';

export default {
  setup() {
    const now = ref(new Date());
    onMounted(() => {
      setInterval(() =>  = new Date(), 1000);
    });
    return {
      now,
    };
  },
};

3. Comparative analysis

We may have forgotten how strange Vue's code is from the perspective of standard JS modules:

  • mounted Modified in Where is the data created? We're in the moduledefault The corresponding field is not found in the object members, butdataThere is this field in another object returned within;
  • anddata Returned in now Not real, either , but The initial value ofdatamiddle setInterval RevisenowThe rendering time cannot be updated;
  • If you want to reuse this data and its update logic, you must write a copy of this structure separately and then use the specialmixinFunctions are mixed into the constructor parameters of the current component.

All this is because of the entire module default The object is actuallyvmThe constructor parameters of the object. Behind it is the object creation logic hidden. When constructing the object, some fields at different levels in the constructor parameters are bound to vm on the object.

Many newbies may have made a mistake, data The data fields returned in propsmethodsorcomputedThe fields in the name crash (especially using fields named data) cannot be directly discovered by the IDE during the encoding stage. It is because of the above reasons that these fields are created at different locations and are bound to the same object only when constructed later, resulting in conflicts that can only be discovered during runtime.

In Vue3, it is changed to providerefreactivetoRefonMountedImplementation of equal functions, in the example:

  • existsetupSeen innowThat is for binding
  • ReviseYou can see the update of the page status;
  • If you want to encapsulate this data processing, you only need tonowandonMountedProcessing and extracting it into the same function, thennowJust go back, no longer need a black boxmixindeal with.

It can be said that Vue3 directly handed over the decision-making power of response data creation and life cycle notification callbacks to the developers through APIs, which is more intuitive and controllable.

4. API Description

Here are some commonly used responsive data related APIs:ref, reactive andtoRefs

(1) ref

The ref used in the above example can wrap a data into a responsive data proxy object.

const count = ref(0);
(); // => 0

++;
(); // => 1

When you modify the properties of the proxy object, the location using count in the template will respond to the data changes and update the data state in the view.

(2) reactive

For responsive encapsulation of objects, userefA little troublesome:

const state = ref({
  count: 0,
});
(); // => 0

++;
(); // => 1

You can use it insteadreactive, modify it like operating fields of ordinary objects count You can update the view:

const state = reactive({
  count: 0,
});
(); // => 0

++;
(); // => 1

To proxy objectsstate Adding new fields can also trigger view updates.

(3) toRefs

Sometimes, the name of the object is too long, and we want to use the internal fields of the object directly in the template, but it is not possible to use deconstruction directly:

import { reactive } from 'vue';

export default {
  setup() {
    const position = reactive({
      x: 0,
      y: 0,
    });
    return {
      // Error, the deconstructed x, y does not have a responsive proxy.  After binding to a template, data changes cannot trigger view updates      ...position,
    };
  },
};

In this case, usetoRefsAfter processing, deconstruct the assignment:

import { reactive, toRefs } from 'vue';

export default {
  setup() {
    const position = reactive({
      x: 0,
      y: 0,
    });
    return {
      ...toRefs(position),
    };
  },
};

But it needs to be paid attention totoRefsOnly process callspositionThe existing field, if afterpositionAdding a new field will not trigger view updates.

The above is a brief analysis of the detailed content of Vue 3.0's assembly API (I). For more information about Vue assembly API, please follow my other related articles!