The response of vue2. X

Implementation principle:

  • Object types: Intercepts reading and modifying attributes via Object.defineProperty() (data hijacking).

  • Array types: Interception is implemented by overriding a series of methods that update an array. The array change method is wrapped.

Object.defineProperty(data, 'count', {
    get () {}, 
    set () {}
})
Copy the code

Existing problems:

  • The interface will not be updated when adding or deleting properties.
  • Modify the array directly by subscript, the interface does not automatically update.

Case:

let person = {
  name: 'Joe'.age: 18,}// Simulate the reactive implementation in Vue2
let p = {};
Object.defineProperty(p, 'name', {
  configurable: true.// called when name is read
  get(){
    return person.name;
  }
  // called when modifying name
  set(value){
    console.log('Changed the name property, I found, I'm going to update the page! ') person.name = value; }})Object.defineProperty(p, 'age', {
  configurable: true.// called when age is read
  get(){
    return person.age;
  }
  // Called when age is modified
  set(value){
    console.log('Changed the age property, I noticed, I'm going to update the page! ') person.age = value; }})Copy the code

Responsiveness of Vue3.0

Implementation principle:

  • throughProxy(proxy) : Intercepts the change of any property in the object, including: reading and writing of property value, adding property, deleting property, etc.
  • throughReflect(Reflection) : Operates on the properties of the source object.
  • Proxy and Reflect as described in the MDN documentation:
    • Proxy:developer.mozilla.org/zh-CN/docs/…

    • Reflect:developer.mozilla.org/zh-CN/docs/…

new Proxy(data, {
// Intercepts reading property values
  get(target, prop) {
        return Reflect.get(target, prop)
  },
  // Intercepts setting property values or adding new properties
  set(target, prop, value) {
        return Reflect.set(target, prop, value)
  },
  // Intercepts delete attributes
  deleteProperty(target, prop) {
        return Reflect.deleteProperty(target, prop)
  }
})
Copy the code

Case:

let person = {
    name: 'Joe'.age: 18
}

// Simulate Vue3 to implement responsiveness
const p = new Proxy(person, {
    // called when reading some property of p
    get(target, propName){
      console.log('Someone read p's${propName}Attribute `);
      return Reflect.get(target, propName);
    },

    // called when modifying an attribute of p or adding an attribute to p
    set(target, propName, value){
      console.log('Someone has modified p's${propName}Properties, I'm going to update the interface);
      Reflect.set(target, propName, value);
    },

    // when an attribute of p is deleted
    deleteProperty(target, propName){
      console.log('Someone deleted p's${propName}Properties, I'm going to update the interface);
      return Reflect.deleteProperty(target, propName); }})Copy the code