In the last article, I wrote about constructing options, data as internal data, and there are many things worth discussing. Vue official document provides a reference link under data for in-depth response principle. This article mainly records the deep learning of response principle.

Three examples

Case 1

import Vue from "vue/dist/vue.js"; 

Vue.config.productionTip = false;

const myData = {
  n: 0
}
console.log(myData)

new Vue({
  data: myData,
  template: ` 
      
{{n}}
`
}).$mount("#app"); setTimeout(() = >{ myData.n += 10 console.log(myData) },3000) Copy the code

It starts with {n:0} and immediately becomes {n:(…) when passed to new Vue. }

Case 2

Getter and setter

Getters and setters are new properties for ES6

MDN – getter and setter

For example,

letObj0 = {last name:"Bad"The name:"Things".age: 18
};

// Get the name

letObj1 = {last name:"Bad"The name:"Things", name () {return thisThe last name +this. Name; },age: 18
};

console.log("Requirement 1:"+ obj1. name ());// Can you delete the parentheses after the name? No, because it's a function
// How to remove the parentheses?

// Requirement 2, the name can be obtained without parentheses

letObj2 = {last name:"Bad"The name:"Things", get name () {return thisThe last name +this. Name; },age: 18
};

console.log("Requirement 2:"+ obj2. name);// Summary: This is how getters are used. Function without parentheses, that's all.

// Requirement 3: The name can be written

letObj3 = {last name:"Bad"The name:"Things", get name () {return thisThe last name +this. Name; }, set name (XXX) {this. Last name = XXX [0];
    this. Name = XXX. The substring (1);
  },
  age: 18}; Obj3. Name ="Good stuff.";

console.log('Requirement three: Last nameThe ${obj3. Last name}Name,The ${obj3. Name}`);

// Summary: this is how setters are used. Trigger the set function with = XXX
Copy the code

console

Print obj3

As you can see, names can be read and written, but there is no name attribute. Get names and set names are used to simulate operations on names.

Object.defineProperty

The object.defineProperty () method directly defines a new property on an Object, or modifies an existing property of an Object, and returns the Object.

If you want to change the name of obj3, you need to redefine _xxx, because XXX doesn’t actually exist.

letObj0 = {last name:"Bad"The name:"Things".age: 18
};

// Get the name

letObj1 = {last name:"Bad"The name:"Things", name () {return thisThe last name +this. Name; },age: 18
};

console.log("Requirement 1:"+ obj1. name ());// Can you delete the parentheses after the name? No, because it's a function
// How to remove the parentheses?

// Requirement 2, the name can be obtained without parentheses

letObj2 = {last name:"Bad"The name:"Things", get name () {return thisThe last name +this. Name; },age: 18
};

console.log("Requirement 2:"+ obj2. name);// Summary: This is how getters are used. Function without parentheses, that's all.

// Requirement 3: The name can be written

letObj3 = {last name:"Bad"The name:"Things", get name () {return thisThe last name +this. Name; }, set name (XXX) {this. Last name = XXX [0];
    this. Name = XXX. The substring (1);
  },
  age: 18
};

/ / change
var _xxx = 0
Object.defineProperty(obj3,'xxx', {get(){
    return _xxx
  },
  set(value){
    _xxx = value
  }
})

obj3.姓名 = "Good stuff.";

console.log('Requirement three: Last nameThe ${obj3. Last name}Name,The ${obj3. Name}`);
console.log(obj3)

// Summary: this is how setters are used. Trigger the set function with = XXX
Copy the code

Example 3

conclusion

  1. Object.defineProperty

    You can add a value property to an object, you can add a getter/setter to an object, and the getter/setter is used to monitor the read and write of the property.

  2. The agent

    A design pattern in which a vm is solely responsible for reading and writing properties of myData objects, so that VM is the proxy of myData, so it is better to use VM

  3. vm = new Vue({data:myData})

    Will make the VM a proxy for myData

    All properties of myData are monitored (in case the VM does not know that the myData property has changed)

    The VM knows that the myData property has changed and can call render(data) UI = render(data)

Schematic diagram

If data has multiple attributes m, n, k, then there will be get M, get N, get K, and so on

Data for Vue — reactive

const vm = new Vue({data:{n:0}})

If you modify vm.n, then n in the UI responds, and Vue2 responds data via Object.defineProperty

What is a responsive Web page?

If you change the size of the window, the content of the page will respond accordingly, which is a responsive page

Vue.setthis.$set

Let’s start with an example

import Vue from "vue/dist/vue.js";

Vue.config.productionTip = false;

new Vue({
  data: {},
  template: ` 
      
{{n}}
`
}).$mount("#app"); Copy the code

Vue has an error indicating that n is not defined, but is referenced in render

Object.defineproperty (obj,’n’,{… }) must have an ‘n’ to listen on and delegate obj.n, where data is null.

Look at the following example

import Vue from "vue/dist/vue.js";

Vue.config.productionTip = false;

new Vue({
  data: {
    obj: {
      a: 0 // obj. A will be listened by Vue & proxy}},template: ` 
      
{{obj.b}}
`
.methods: { setB() { this.obj.b = 1; } } }).$mount("#app"); Copy the code

Clicking the button on the page doesn’t show a 1, but it doesn’t show an error either

Why is that?

Because Vue only checks the first level properties, it will not report an error if the first level is ok. Clicking won’t show a 1 either, because Vue can’t listen to obJ.B, which never existed in the first place

Use vue. set or this.$set to solve this problem

    setB() {
      // this.obj.b = 1;
      Vue.set(this.obj,'b'.1)
      / / or
      this.$set(this.obj,'b'.1)}Copy the code

Function:

The new key

Automatically create agents and listeners (if not already created)

UI updates are triggered, but not immediately

Change the way

For example

import Vue from "vue/dist/vue.js";

Vue.config.productionTip = false;

new Vue({
  data: {
    array: ["a"."b"."c"]},template: ` 
      
{{array}}
`
.methods: { setD() { this.array[3] = "d"; // the page will not display 'd' this.$set(this.array,3."d"); // the page displays 'd' } } }).$mount("#app"); Copy the code

For example, the array length can always increase, and the subscript is key, so there is no way to declare all the keys in advance, and Vue cannot detect new subscripts. Using Vue.

Yu Creek’s approach is to tamper with the array API, Vue documentation – change method

push()
pop()
shift()
unshift()
splice()
sort()
reverse()
Copy the code

These 7 apis are tampered with by Vue, which updates the UI when called

For example, let me rewrite the example above

setD(){
  // this.$set(this.array,3,"d"); 
  this.array.push('d');
}
Copy the code

Print array, and you can see that the prototype has these seven methods

This.$set does not automatically add listeners and proxies when applied to arrays.

When using Vue’s array change API, listeners and proxies are handled automatically, and the UI is updated, so new array keys are best done through these 7 apis.