D3 - Handle reactivity in Vue3

Reactivity is the ability for a variable (array, string, number, object, etc) to update when its value or any other variable that it makes reference to is changed after declaration.

By default, JavaScript isn’t reactive. It means that if we create the variable boy and reference it in part A of our application, then proceed to modify boy in part B, part A will not update with the new value of boy.

let framework = 'Vue';let sentence = `${framework} is awesome`;console.log(sentence) // logs "Vue is awesome"framework = 'React';console.log(sentence)//should log "React is awesome" if 'sentence' is reactive.

check it live here ⇒ https://jsbin.com/cevocewigi/edit?js,console

Another example ⇒ Let’s take a simple Markdown editor  as an example. It usually has two panes: one for writing the Markdown code (which modifies the underlying model), and one for previewing the compiled HTML (which shows the updated view).

Reactivity in Vue:

In Vue 2.x, propscomputed , and data() were all reactive by default, with the exception of properties that are not present in data when such components are created. Vue 2 and option api uses Vue.observable() to make values reactive.

Reactivity in Vue 3:

In Vue reactive method, is the equivalent of Vue.observable() in Vue 2.6. But new reactive system is based on ES6 proxy and Reflect api. To understand behind the scene of Vue 3 reactivity, you should learn the proxy concept.

What is JavaScript proxy

check here, how proxy work in JavaScript with reflect api.

let person = {  name: "David",  age: 27};const handler = {  get(target, property, receiver) {    // track(target, property)    console.log(property) // output: name    return Reflect.get(target, property, receiver)  },  set(target, property, value, receiver) {    // trigger(target, property)    console.log(`${property}: ${value}`) // output: "age: 30" and "hobby: Programming"    return Reflect.set(target, property, value, receiver)  }}let proxy = new Proxy(person, handler);   console.log(person)// get (reading a property value)console.log(proxy.name)  // output: David// set (writing to a property)proxy.age = 30;// set (creating a new property)proxy.hobby = "Programming";console.log(person)

here is the live version ⇒ https://jsbin.com/qetivalezi/edit?js,console

The get and set traps take the following arguments:

  • target: the target object which is wrapped by the proxy
  • property: the property name
  • value: the property value (this argument is used only for set operations)
  • receiver: the object on which the operation takes place (usually the proxy)

The Reflect API methods accepts the same arguments as their corresponding proxy methods.

Vue 3 Reactivity Model

There are some basic methods to controll data reactivity:

  • ref takes a primitive value or a plain object and returns a reactive and mutable ref object. The ref object has only one property value that points to the primitive value or the plain object.
  • reactive takes an object and returns a reactive copy of the object. The conversion is deep and affects all nested properties.
  • readonly takes a ref or an object (plain or reactive) and returns a readonly object to the original. The conversion is deep and affects all nested properties.
  • markRaw returns the object itself and prevents it from being converted to a proxy object.

ref

Takes an inner value and returns a reactive and mutable ref object, which has a single property .value that points to the inner value.

<script setup>import { ref } from 'vue'const msg = ref('Hello World!')</script><template>  <h1>{{ msg }}</h1>  <input v-model="msg"></template>

try it on ⇒ https://sfc.vuejs.org/

reactive

Reactive objects are JavaScript Proxies and behave just like normal objects. The difference is that Vue is able to track the property access and mutations of a reactive object.

<script setup>import { reactive } from 'vue'const state = reactive({ count: 0 })function increment() {  state.count++}</script><template>  <button @click="increment">    {{ state.count }}  </button></template>

try it on ⇒ https://sfc.vuejs.org/