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. Here are some experiments to implement some requirements: 1. Define n with Object.defineProperty

Let data1 = {} object.defineProperty (data1, 'n', {value: 0}) console.log(' Requirement 1: ${data1.n} ')Copy the code

2. N cannot be less than 0

Object.defineproperty (data2, 'n', {get(){return this._n}, Set (value){if(value < 0) return this._n = value}}) console.log(' Requirement 2: ${data2.n} ') data2.n = -1 console.log(' Requirement 2: ${data2.n} ') data2.n = -1 console.log(' Requirement 2: ${data2.n} set to -1 failed ') data2.n = 1 console.log(' Requirement 2: ${data2.n} set to 1 succeeded ')Copy the code

You find that by getting and setting property values through getter and setter methods, you can add conditions to the process that restrict the setting of the raw data, which is listening on data. The problem with this approach, however, is that if someone changes the property value via datA2._n there is no way to avoid the result of the data being modified, so we should not expose the data that can be done by proxy

Function proxy({data}/* const obj = {data :{n:0}}) {function proxy({data :{n:0}}) {const obj = {} // Theoretically you should iterate through all the keys of data, Object.defineproperty (obj, 'n', {get(){return data.n}, Set (value){if(value<0)return data.n = value}}) return obj // obj is the proxy} // data3 is obj console.log(' 表 三 : ${data3.n} ') data3.n = -1 console.log(' Requirement 3: ${data3.n}, set to -1 failed ') data3.n = 1 console.log(' Requirement 3: ${data3.n}, set to 1 succeeded ')Copy the code

However, you can still change the value of the attribute if you pass in the following way

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

So we assign the value of data.n to a variable and delete data.n

function proxy2({data}){
    let value = data.n
  Object.defineProperty(data, 'n', {
    get(){
      return value
    },
    set(newValue){
      if(newValue<0)return
      value = newValue
    }
  })
Copy the code

Vue does similar processing to data, read and write to the attributes of myData objects, let vm object proxy all, make it have non-invasive function, and monitor all data attributes. Vue’s data is reactive. If you modify vm.n, n in the UI responds. Vue2 implements data responsiveness through Object.defineProperty. It records “touched” data properties as dependencies during component rendering. Watcher is then notified when the setter for the dependency fires, causing its associated component to be re-rendered. Vue does not allow dynamic root-level responsive properties to be added to already created instances. However, you can add responsive properties to nested objects using the vue.set (Object, propertyName, value) method. You can also use the vm.$set instance method, which is also an alias for the global vue.set method