What is data responsiveness?

One of the most unique features of Vue is its non-invasive responsive system, according to the vue.js documentation. Data models are just plain old JavaScript objects. And when you modify them, the view is updated. This makes state management very straightforward.

When you pass an ordinary JavaScript object into a Vue instance as the data option, Vue iterates through all of the object’s properties, And use Object.defineProperty to turn all of these properties into getters/setters.

These getters/setters are invisible to the user, but internally they allow Vue to track dependencies and notify changes when the property is accessed and modified.


Object.defineproperty ()

let data2 = {}

data2._n = 0 // _n is used to secretly store n values

Object.defineProperty(data2, 'n', {
  get(){
    return this._n
  },
  set(value){
    if(value < 0) return
    this._n = value
  }
})
Copy the code

Object.defineproperty () can add a value attribute to an Object and a getter/setter to an Object, which monitors the read and write of the attribute.

The problem is that we can change the value of datA2._n by modifying the variable data2._n. To solve this problem, we need to use the proxy:

let data3 = proxy({ data: {n:0}})// The parentheses are anonymous objects that cannot be accessed

function proxy({data} /* Destruct assignment */){
  const obj = {}
  Object.defineProperty(obj, 'n', { 
    get(){
      return data.n
    },
    set(value){
      if(value<0)return
      data.n = value
    }
  })
  return obj // obj is the proxy
}

Copy the code

But the above code can also be modified in the following way:

let myData = {n:0}
let data4 = proxy({ data:myData })
Copy the code

To solve this problem, you also need to add a listener:

let myData5 = {n:0}
let data5 = proxy2({ data:myData5 }) 

function proxy2({data}/* Destruct assignment */){
  let value = data.n
  Object.defineProperty(data, 'n', {
    get(){
      return value
    },
    set(newValue){
      if(newValue<0)return
      value = newValue
    }
  })
  // Add the above sentence, this sentence will listen to data

  const obj = {}
  Object.defineProperty(obj, 'n', {
    get(){
      return data.n
    },
    set(value){
      if(value<0)return
      data.n = value
    }
  })
  
  return obj // obj is the proxy
}

Copy the code

This is probably how Vue implements data responsiveness.

vm = new Vue({data:myData})
Copy the code

Make vm a proxy for myData

Second, all the attributes of myData will be monitored

When the VM detects that the properties of myData have changed, it can call Render (data) to update the view.