Connect with us

Technology

Understanding the New Reactivity System in Vue 3 – SitePoint


Reactivity methods are one of many key components of contemporary front-end frameworks. They’re the magic wand which makes apps extremely interactive, dynamic, and responsive. Understanding what a reactivity system is and the way it may be utilized in follow is an important ability for each net developer.

A reactivity system is a mechanism which routinely retains in sync an information supply (mannequin) with an information illustration (view) layer. Each time the mannequin modifications, the view is re-rendered to mirror the modifications.

Let’s take a easy Markdown editor for instance. It normally has two panes: one for writing the Markdown code (which modifies the underlying mannequin), and one for previewing the compiled HTML (which exhibits the up to date view). Once you write one thing within the writing pane, it’s instantly and routinely previewed within the previewing pane. After all, that is only a easy instance. Typically issues are way more advanced.

In lots of circumstances, the information we wish to show relies on another knowledge. In such a situation, the dependencies are tracked and the information is up to date accordingly. For instance, let’s say now we have a fullName property, which relies on firstName and lastName properties. When any of its dependencies are modified, the fullName property is routinely re-evaluated and the result’s displayed within the view.

Now that we’ve established what reactivity is, it’s time to learn the way the brand new Vue 3 reactivity works, and the way we are able to use it in follow. However earlier than we do that, we’ll take a fast have a look at the previous Vue 2 reactivity and its caveats.

A Transient Exploration of Vue 2 Reactivity

Reactivity in Vue 2 is kind of “hidden”. No matter we put within the knowledge object, Vue makes it reactive implicitly. On the one hand, this makes the developer’s job simpler, however then again it results in much less flexibility.

Behind the scenes, Vue 2 makes use of the ES5 Object.defineProperty() to transform the entire knowledge object’s properties into getters and setters. For every element occasion, Vue creates a dependencies watcher occasion. Any properties collected/tracked as dependencies throughout the element’s render are recorded by the watcher. Afterward, when a dependency’s setter is triggered, the watcher is notified and the element re-renders and updates the view. That is principally how all of the magic works. Sadly, there are some caveats.

Change Detection Caveats

Due to the restrictions of Object.defineProperty(), there are some knowledge modifications that Vue can’t detect. These embody:

  • including/eradicating a property to/from an object (equivalent to obj.newKey = worth)
  • setting array gadgets by index (equivalent to arr[index] = newValue)
  • modifying the size of an array (equivalent to arr.size = newLength)

Thankfully, to cope with these limitations Vue offers us with the Vue.set API methodology, which provides a property to a reactive object, making certain the brand new property can be reactive and thus triggers view updates.

Let’s discover the above circumstances within the following instance:

<div id="app">
  <h1>Howdy! My title is {{ particular person.title }}. I am {{ particular person.age }} years previous.</h1>
  <button @click on="addAgeProperty">Add "age" property</button>
  <p>Listed here are my favourite actions:</p>
  <ul>
    <li v-for="merchandise, index in actions" :key="index">
      {{ merchandise }}
      <button @click on="editActivity(index)">Edit</button>
    </li>
  </ul>
  <button @click on="clearActivities">Clear the actions checklist</button>
</div>
const App = new Vue({
  el: '#app',
  knowledge: {
    particular person: {
      title: "David"
    },
    actions: [
      "Reading books",
      "Listening music",
      "Watching TV"
    ]
  },
  strategies: { 
    
    addAgeProperty() {
      this.particular person.age = 30
    },
    
    editActivity(index) {
      const newValue = immediate('Enter a brand new worth')
      if (newValue) {
        this.actions[index] = newValue
      }
    },
    
    clearActivities() { 
      this.actions.size = 0 
    }
  }
});

Right here’s a CodePen instance.

Within the above instance, we are able to see that not one of the three strategies is working. We are able to’t add a brand new property to the particular person object. We are able to’t edit an merchandise from the actions array by utilizing its index. And we are able to’t modify the size of the actions array.

After all, there are workarounds for these circumstances and we’ll discover them within the subsequent instance:

const App = new Vue({
  el: '#app',
  knowledge: {
    particular person: {
      title: "David"
    },
    actions: [
      "Reading books",
      "Listening music",
      "Watching TV"
    ]
  },
  strategies: { 
    
    addAgeProperty() {
      Vue.set(this.particular person, 'age', 30)
    },
    
    editActivity(index) {
      const newValue = immediate('Enter a brand new worth')
      if (newValue) {
        Vue.set(this.actions, index, newValue)
      }
    },
    
    clearActivities() { 
      this.actions.splice(0)
    }
  }
});

Right here’s a CodePen instance.

On this instance, we use the Vue.set API methodology so as to add the brand new age property to the particular person object and to pick out/modify a selected merchandise from the actions array. Within the final case, we simply use the JavaScript built-in splice() array methodology.

As we are able to see, this works, but it surely’s a bit hacky and results in inconsistency within the codebase. Thankfully, in Vue 3 this has been resolved. Let’s see the magic in motion, within the following instance:

const App = {
  knowledge() {
    return {
      particular person: {
        title: "David"
      },
      actions: [
        "Reading books",
        "Listening music",
        "Watching TV"
      ]
    }
  },
  strategies: { 
    
    addAgeProperty() {
      this.particular person.age = 30
    },
    
    editActivity(index) {
      const newValue = immediate('Enter a brand new worth')
      if (newValue) {
        this.actions[index] = newValue
      }
    },
    
    clearActivities() { 
      this.actions.size = 0 
    }
  }
}

Vue.createApp(App).mount('#app')

Right here’s a CodePen instance.

On this instance, which makes use of Vue 3, we revert to the built-in JavaScript performance, used within the first instance, and now all strategies work like a allure.

In Vue 2.6, a Vue.observable() API methodology was launched. It exposes, to some extent, the reactivity system permitting builders to make objects reactive explicitly. Really, that is the very same methodology Vue makes use of internally to wrap the knowledge object and is helpful for making a minimal, cross-component state retailer for easy eventualities. However regardless of its usefulness, this single methodology can’t match the ability and suppleness of the complete, feature-rich reactivity API which ships with Vue 3. And we’ll see why within the subsequent sections.

Observe: as a result of Object.defineProperty() is an ES5-only and un-shimmable function, Vue 2 doesn’t assist IE8 and beneath.

How Vue 3 Reactivity Works

The reactivity system in Vue 3 was fully rewritten with a view to reap the benefits of the ES6 Proxy and Replicate APIs. The brand new model exposes a feature-rich reactivity API which makes the system way more versatile and highly effective than earlier than.

The Proxy API permits builders to intercept and modify low-level object operations on a goal object. A proxy is a clone/wrapper of an object (referred to as goal) and gives particular features (referred to as traps), which reply to particular operations and override the built-in conduct of JavaScript objects. In case you nonetheless want to make use of the default conduct, you need to use the corresponding Reflection API, whose strategies, because the title suggests, mirror these of the Proxy API. Let’s discover an instance to see how these APIs are utilized in Vue 3:

let particular person = {
  title: "David",
  age: 27
};

const handler = {
  get(goal, property, receiver) {
    
    console.log(property) 
    return Replicate.get(goal, property, receiver)
  },
  set(goal, property, worth, receiver) {
    
    console.log(`${property}: ${worth}`) 
    return Replicate.set(goal, property, worth, receiver)
  }
}

let proxy = new Proxy(particular person, handler);   

console.log(particular person)


console.log(proxy.title)  


proxy.age = 30;


proxy.pastime = "Programming";

console.log(particular person) 

Right here’s a CodePen instance.

To create a brand new proxy, we use the new Proxy(goal, handler) constructor. It takes two arguments: the goal object (particular person object) and the handler object, which defines which operations might be intercepted (get and set operations). Within the handler object, we use the get and set traps to trace when a property is learn and when a property is modified/added. We set console statements to make sure that the strategies work appropriately.

The get and set traps take the next arguments:

  • goal: the goal object which is wrapped by the proxy
  • property: the property title
  • worth: the property worth (this argument is used just for set operations)
  • receiver: the article on which the operation takes place (normally the proxy)

The Replicate API strategies accepts the identical arguments as their corresponding proxy strategies. They’re used to implement the default conduct for the given operations, which for the get lure is returning the property title and for the set lure is returning true if the property was set or false if not.

The commented observe() and set off() features are particular to Vue and are used to trace when a property is learn and when a property is modified/added. In consequence, Vue re-runs the code that’s utilizing that property.

Within the final a part of the instance, we use a console assertion to output the unique particular person object. Then we use one other assertion to learn the property title of the proxy object. Subsequent, we modify the age property and create a brand new pastime property. Lastly, we output the particular person object once more to see that it has been up to date appropriately.

And that is how Vue 3 reactivity works in a nutshell. After all, the actual implementation is far more advanced, however hopefully the instance introduced above is sufficient so that you can grasp the primary concept.

There’s additionally a few issues while you use Vue 3 reactivity:

  • it solely works on browsers supporting ES6+
  • the reactive proxy isn’t equal to the unique object

Exploring the Vue 3 Reactivity API

Lastly, we get to the Vue 3 reactivity API itself. Within the following sections, we’ll discover the API strategies divided into logical teams. I put strategies in teams as a result of I believe they’re simpler to recollect when introduced in that means. Let’s begin with the fundamentals.

Primary Strategies

The primary group consists of probably the most fundamental strategies for controlling knowledge reactivity:

  • ref takes a primitive worth or a plain object and returns a reactive and mutable ref object. The ref object has just one property worth that factors to the primitive worth or the plain object.
  • reactive takes an object and returns a reactive copy of the article. The conversion is deep and impacts all nested properties.
  • readonly takes a ref or an object (plain or reactive) and returns a readonly object to the unique. The conversion is deep and impacts all nested properties.
  • markRaw returns the article itself and prevents it from being transformed to a proxy object.

Let’s now see these strategies in motion:

<h1>Howdy, Vue 3 Reactivity API! :)</h1>
<hr>
<p><sturdy>Counter:</sturdy> {{ counter }}</p>
<button @click on="counter++">+ Increment counter</button>
<br><br>
<button @click on="counter--">- Decrement counter</button>
<hr>
<h3>Howdy! My title is <mark>{{ particular person.title }}</mark>. I am <mark>{{ particular person.age }}</mark> years previous.</h3>
<p>Edit particular person's title
  <enter v-model="particular person.title" placeholder="title" /> and age
  <enter v-model="particular person.age" placeholder="age" />
</p>
<hr>
<p><sturdy>PI:</sturdy> {{ math.PI }}</p>
<button @click on="math.PI = 6.28">Double PI</button> <span>(The console output after the button is clicked: <em>"Set operation on key 'PI' failed: goal is readonly."</em>)</span>
<hr>
<h3>Alphabet Numbers</h3>
<desk>
  <tr>
    <th>Letter</th>
    <th>Quantity</th>
  </tr>
  <tr v-for="(worth, key) in alphabetNumbers">
    <td>{{ key }}</td>
    <td>{{ worth }}</td>
  </tr>
</desk>
<br>
<button @click on="alphabetNumbers.B = 3">Change the worth of B to three</button><span> (Really the letter B <em>is</em> modified to quantity 3 - <button @click on="showValue">Present the worth of B</button>, but it surely's <em>not</em> tracked by Vue.)</span>
import { ref, reactive, readonly, markRaw, isRef, isReactive, isReadonly, isProxy, onMounted } from 'vue';

export default {
  setup () {
    const counter = ref(0)
    const particular person = reactive({
      title: 'David',
      age: 36
    })
    const math = readonly({
      PI: 3.14
    })
    const alphabetNumbers = markRaw({
      A: 1,
      B: 2,
      C: 3
    })

    const showValue = () => {
      alert(`The worth of B is ${alphabetNumbers.B}`)
    }

    onMounted(() => {
      console.log(isRef(counter)) 
      console.log(isReactive(particular person)) 
      console.log(isReadonly(math)) 
      console.log(isProxy(alphabetNumbers)) 
    })

    return {
      counter,
      particular person,
      math,
      alphabetNumbers,
      showValue
    }
  }
};

See the Pen
Vue 3 Reactivity API 1 Edited
by SitePoint (@SitePoint)
on CodePen.

On this instance, we discover using the 4 fundamental reactivity strategies.

First, we create a counter ref object with a price of 0. Then, within the view, we put two buttons which increment and decrement thecounter’s worth. Once we use these buttons, we see that the counter is really reactive.

Second, we create a particular person reactive object. Then, within the view, we put two enter controls for modifying an individual’s title and an individual’s age respectively. As we edit the particular person’s properties, they’re up to date instantly.

Third, we create a math readonly object. Then, within the view, we set a button for doubling the worth of the math‘s PI property. However once we click on the button, an error message is proven within the console, telling us that the article is readonly and that we are able to’t modify its properties.

Lastly, we create an alphabetNumbers object, which we don’t wish to convert to proxy, and mark it as uncooked. It comprises all alphabet letters with their corresponding numbers (for brevity, solely the primary three letters are used right here). This order is unlikely to be modified, so we deliberately hold this object plain, which is nice for the efficiency. We render the article content material in a desk and set a button that modifications the worth of B property to 3. We do that to indicate that though the article may be modified, this doesn’t result in view re-rendering.

markRaw is nice for objects we don’t require to be reactive, equivalent to an extended checklist of nation codes, colour names and their corresponding hexadecimal numbers, and so forth.

Lastly, we use the sort examine strategies, described within the subsequent part, to check and decide the kind of every object we’ve created. We fireplace these checks, when the app renders initially, by utilizing the onMounted() lifecycle hook.

Kind Examine Strategies

This group comprises all 4 kind checkers talked about above:

  • isRef checks if a price is a ref object.
  • isReactive checks if an object is a reactive proxy created by reactive or created by readonly by wrapping one other proxy created by reactive.
  • isReadonly checks if an object is a readonly proxy created by readonly.
  • isProxy checks if an object is a proxy created by reactive or readonly.

Extra Refs Strategies

This group comprises further ref strategies:

  • unref returns the worth of a ref.
  • triggerRef executes any results tied to a shallowRef manually.
  • customRef creates a custom-made ref with express management over its dependency monitoring and updates triggering.

Shallow Strategies

The strategies on this group are “shallow” equivalents of the ref, reactivity, and readonly:

  • shallowRef creates a ref which tracks solely its worth property with out making its worth reactive.
  • shallowReactive creates a reactive proxy which tracks solely its personal properties excluding nested objects.
  • shallowReadonly creates a readonly proxy which makes solely its personal properties readonly excluding nested objects.

Let’s make these strategies simpler to know by analyzing the next instance:

<h1>Howdy, Vue 3 Reactivity API! :)</h1>
<hr>
<h2>Shallow Ref</h2>
<p><sturdy>Settings:</sturdy> {{settings}}  
  <br><br>
  Width: <enter v-model="settings.width" /> 
  Peak: <enter v-model="settings.top" />
  <br><br>
  <button @click on="settings = { width: 80, top: 80 }">
    Change the settings' worth
  </button>
</p>
<hr>
<h2>Shallow Reactive</h2>
<p><sturdy>SettingsA:</sturdy> {{settingsA}}
  <br><br>
  Width: <enter v-model="settingsA.width" /> 
  Peak: <enter v-model="settingsA.top" />
  <br><br>
  X: <enter v-model="settingsA.coords.x" /> 
  Y: <enter v-model="settingsA.coords.y" />
</p>
<hr>
<h2>Shallow Readonly</h2>
<p><sturdy>SettingsB:</sturdy> {{settingsB}} 
  <br><br>
  Width: <enter v-model="settingsB.width" /> 
  Peak: <enter v-model="settingsB.top" />
  <br><br>
  <span>(The console output after attempting to alter the <sturdy>width</sturdy> or <sturdy>top</sturdy> is: <em>"Set operation on key 'width/top' failed: goal is readonly."</em>)</span>
  <br><br>
  X: <enter v-model="settingsB.coords.x" /> 
  Y: <enter v-model="settingsB.coords.y" />
</p>
import {ref, shallowRef, shallowReactive, shallowReadonly, isRef, isReactive, isReadonly, onMounted } from 'vue';

export default {
  setup () {
    const settings = shallowRef({
      width: 100,
      top: 60
    })
    const settingsA = shallowReactive({
      width: 110,
      top: 70,
      coords: {
        x: 10,
        y: 20
      }
    })
    const settingsB = shallowReadonly({
      width: 120,
      top: 80,
      coords: {
        x: 20,
        y: 40
      }
    })

    onMounted(() => {
      console.log(isReactive(settings)) 
      console.log(isReactive(settingsA)) 
      console.log(isReactive(settingsA.coords)) 
      console.log(isReadonly(settingsB)) 
      console.log(isReadonly(settingsB.coords)) 
    })

    return {
      settings,
      settingsA,
      settingsB
    }
  }
}; 

See the Pen
Vue 3 Reactivity API 2 Edited
by SitePoint (@SitePoint)
on CodePen.

This instance begins with the creation of a settings shallow ref object. Then, within the view, we add two enter controls to edit its width and top properties. However as we attempt to modify them, we see that they don’t replace. To repair that we add a button which modifications the entire object with all of its properties. Now it really works. It’s because the worth‘s content material (width and top as particular person properties) isn’t transformed to a reactive object however the mutation of the worth (the article as an entire) continues to be tracked.

Subsequent, we create a settingsA shallow reactive proxy which comprises the width and top properties and a nested coords object with the x and y properties. Then, within the view, we set an enter management for every property. Once we modify the width and top properties, we see that they’re reactively up to date. However once we attempt to modify the x and y properties, we see that they’re not tracked.

Lastly, we create a settingsB shallow readonly object with the identical properties as settingsA. Right here, once we attempt to modify the width or top property, an error message is proven within the console telling us that the article is readonly and we are able to’t modify its properties. Then again, the x and y properties may be modified with no downside.

The nested coords object, from each of the final examples, isn’t affected by the conversion, and it’s stored plain. Which means it may be freely modified however none of its modifications might be tracked by Vue.

Conversion Strategies

The subsequent three strategies are used for changing a proxy to ref(s) or a plain object:

  • toRef creates a ref for a property on a supply reactive object. The ref retains the reactive connection to its supply property.
  • toRefs converts a reactive object to a plain object. Every property of the plain object is a ref pointing to the corresponding property of the unique object.
  • toRaw returns the uncooked, plain object of a reactive or readonly proxy.

Let’s see how these conversions works within the following instance:

<h1>Howdy, Vue 3 Reactivity API! :)</h1>
<hr>
<h3>Howdy! My title is <mark>{{ particular person.title }}</mark>. 
  I am <mark>{{ particular person.age }}</mark> years previous. 
  My pastime is programming.</h3>
<hr>
<h2>To Ref</h2>
<p> 
  Identify (ref): <enter v-model="title" /> 
  Particular person's title: <enter v-model="particular person.title" />
</p>
<hr>
<h2>To Refs</h2>
<p> 
  PersonDetails' age (ref): <enter v-model="personDetails.age.worth" /> 
  Particular person's age: <enter v-model="particular person.age" />
</p>
<hr>
<h2>To Uncooked</h2>
<p> 
  <sturdy>RawPerson's pastime:</sturdy> {{rawPerson.pastime}}
  <br><br>
  RawPerson's pastime: <enter v-model="rawPerson.pastime" />
</p>
import { reactive, toRef, toRefs, toRaw, isReactive, isRef, onMounted } from 'vue';

export default {
  setup () {
    const particular person = reactive({
      title: 'David',
      age: 30,
      pastime: 'programming'
    })
    const title = toRef(particular person, 'title')
    const personDetails = toRefs(particular person)
    const rawPerson = toRaw(particular person)

    onMounted(() => {
      console.log(isRef(title)) 
      console.log(isRef(personDetails.age)) 
      console.log(isReactive(rawPerson)) 
    })

    return {
      particular person,
      title,
      personDetails,
      rawPerson
    }
  }
};

See the Pen
Vue 3 Reactivity API 3 Edited
by SitePoint (@SitePoint)
on CodePen.

On this instance, we first create a base particular person reactive object, which we’ll use as a supply object.

Then we convert the particular person’s title property to a ref with the identical title. Then, within the view, we add two enter controls — one for the title ref and one for the particular person’s title property. Once we modify one in every of them, the opposite is up to date accordingly so the reactive connection between them is stored.

Subsequent, we convert all of an individual’s properties to particular person refs contained within the personDetails object. Then, within the view, we add two enter controls once more to check one of many refs we’ve simply created. As we are able to see, the personDetails’ age is in full sync with the particular person’s age property, simply as within the earlier instance.

Lastly, we convert the particular person reactivity object to a rawPerson plain object. Then, within the view, we add an enter management for modifying the rawPerson’s pastime property. However as we are able to see, the transformed object isn’t tracked by Vue.

Computed and Watch Strategies

The final group of strategies are for computing advanced values and “spying” on sure worth(s):

  • computed takes a getter operate as argument and returns an immutable reactive ref object.
  • watchEffect runs a operate instantly and reactively tracks its dependencies and re-runs it each time the dependencies are modified.
  • watch is the precise equal of the Choices API this.$watch and the corresponding watch possibility. It’s expecting a particular knowledge supply and applies uncomfortable side effects in a callback operate when the watched supply has modified.

Let’s think about the next instance:

<h1>Howdy, Vue 3 Reactivity API! :)</h1>
<hr>
<h3>Howdy! My title is <mark>{{ fullName }}</mark>.</h3>
<p> 
  First Identify: <enter v-model="firstName" /> 
  Final Identify: <enter v-model="lastName" />
</p>
<hr>
<sturdy>Quantity:</sturdy> {{quantity}}
<br><br>
<button @click on="quantity++">+ Increment quantity</button>
<hr>
<sturdy>State:</sturdy> {{state}}
<br><br>
<button @click on="state = state == 'taking part in' ? 'paused' : 'taking part in' ">Change state</button>
import { ref, computed, watch, watchEffect } from 'vue';

export default {
  setup () {
    
    const firstName = ref('David')
    const lastName = ref('Wilson')
    const fullName = computed(() => {
      return firstName.worth + ' ' + lastName.worth
    })
    
    const quantity = ref(0)
    watchEffect(() => {
      if (quantity.worth != 0 && quantity.worth % 3 == 0) {
          alert("The amount's worth may be divided into 3")
        }
    })
    
    const state = ref('taking part in')
    watch(state, (newValue, oldValue) =>
      alert(`The state was modified from ${oldValue} to ${newValue}`)
    )

    return {
      firstName,
      lastName,
      fullName,
      quantity,
      state
    }
  }
}; 

See the Pen
Vue 3 Reactivity API 4 Edited
by SitePoint (@SitePoint)
on CodePen.

On this instance, we create a fullName computed variable which bases its computation on the firstName and lastName refs. Then, within the view, we add two enter controls for modifying the 2 components of the complete title. And as we are able to see, once we modify whichever half, the fullName is re-calculated and the result’s up to date.

Subsequent, we create a quantity ref and set a watch impact for it. Each time quantity is modified, the impact will run the callback operate. To show that, within the view, we add a button that increments the amount by one. We set a situation within the callback operate that assessments whether or not the amount’s worth may be divided into 3, and when it returns true an alert message is proven. The impact is run as soon as when the app is initiated and the amount’s worth is about, after which once more each time the amount’s worth is modified.

Lastly, we create a state ref and set a watch operate to trace it for modifications. As quickly because the state modifications, the callback operate might be executed. On this instance, we add a button that toggles the state between taking part in and paused. Each time this occurs, an alert message is proven.

watchEffect and watch look just about an identical by way of performance, however they’ve some distinct variations:

  • watchEffect treats all reactive properties included within the callback operate as dependencies. So if the callback comprises three properties, they’re all tracked for modifications implicitly.
  • watch tracks solely the properties that we’ve included as arguments within the callback. Additionally, it offers each the earlier and present worth of the watched property.

As you possibly can see, the Vue 3 reactivity API gives loads of strategies for quite a lot of use circumstances. The API is kind of massive, and on this tutorial I’ve solely explored the fundamentals. For a extra in-depth exploration, particulars and edge circumstances, go to the Reactivity API documentation.

Conclusion

On this article, we coated what a reactivity system is and the way it’s carried out in Vue 2 and Vue 3. We noticed that Vue 2 has some drawbacks which might be efficiently resolved in Vue 3. Vue 3 reactivity is a whole rewrite based mostly on the fashionable JavaScript options. Let’s summarize its benefits and drawbacks.

Benefits:

  • It may be used as a standalone package deal. You should utilize it with React, for instance.
  • It gives rather more flexibility and energy due to its feature-rich API.
  • It helps extra knowledge constructions (Map, WeakMap, Set, WeakSet).
  • It has higher efficiency. Solely the wanted knowledge is made reactive.
  • Knowledge manipulation caveats from Vue 2 are resolved.

Disadvantages:

  • It solely works on browsers supporting ES6+.
  • The reactive proxy doesn’t equal to the unique object by way of id comparability (===).
  • It requires extra code in comparison with the Vue 2 “automated” reactivity.

The underside line is that Vue 3 reactivity is a versatile and highly effective system, which can be utilized each by Vue and non-Vue builders. No matter your case is, simply seize it and begin constructing superior issues.

Click to comment

Leave a Reply

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