In-depth understanding of Vue's data responsiveness

In-depth understanding of Vue's data responsiveness

1. ES syntax getter and setter

Before you start to understand the data responsiveness principle of Vue, you should first understand the specific usage of getter and setter methods in ES syntax.

Getter and setter methods are a way to add virtual properties to an object using the get and set keywords. This property does not actually exist, but is simulated by a getter function and a setter function. The purpose is to set a storage function and a value-getter function for a certain attribute, intercept the access behavior of the attribute, and make some restrictions on the access of the attribute. As shown below (the following code comes from mdn)

Getter methods

const obj = {
  log: ['a', 'b', 'c'],
  get latest() { //Add the get keyword before the normal method if (this.log.length == 0) {
      return undefined;
    }
    return this.log[this.log.length - 1];
  }
}

console.log(obj.latest); // Output c, get the property name without brackets

Setter Methods

const language = {
  set current(name) {
    this.log.push(name);
  },
  log: []
}

language.current = 'EN';
language.current = 'FA';

console.log(language.log); // Output Array ["EN", "FA"]

2. defineProperty in ES syntax

The defineProperty method defines a new property directly on an object, or modifies an existing property of an object, and returns this object, which can be used to modify or add properties to an object after it is defined.
The syntax is:

Object.defineProperty(obj, prop, descriptor)

Add general properties:

let data = {
  m: 0
}

Object.defineProperty(data, 'n', {
  value: 1 //The value of the added attribute is its value})
console.log(`${data.n}`) // will output n value as 1

Can also be used to add getters and setters for virtual properties

let data1 = {
    _n: 0
}

Object.defineProperty(data1, 'n', {
  get(){
    return this._n
  }, 
  set(value){
    if(value < 0) return
    this._n = value
  }//Just write get / set }) //Since the virtual attribute is specified as n, that is, get n(){}, set n(value){}, there is no need to write n in the function definition

3. Vue's proxy and monitoring of data

Agent, that is, proxy, simply put, some of my own things I do not handle myself, but give them to someone else to do it for me. The person who does the job is the agent. There are two key points in this logic that need to be clarified. The agent is the person who handles the operations, but the things he handles the operations do not belong to him, but to the person who entrusts him to be the agent.

Therefore, by analogy to the Vue data proxy, the proxy is the data{} data object, and the proxy is the Vue instance vm. The data{} data object wants to proxy vm to manage the data operations in the data{} data object. Therefore, the data{} data object is only responsible for the production of internal data, and the management and operation of the produced data are entirely handled by the vm.

So how does vm control and operate the data in the data{} data object? In other words, how does vm know in time when any attribute value in the data{} data object changes?

Therefore, the getter and setter methods in the ES syntax are used. Any operation on the properties controlled by the getter and setter methods will be detected by these two functions. The properties formed by the getter and setter methods are virtual properties and do not really exist. Therefore, if the user wants to modify the properties of the data{} data object directly without going through the proxy vm, the corresponding entity properties cannot be obtained and can only be modified through the getter and setter methods, and the modification will definitely be detected by the vm.

Therefore, in order to achieve full control over the data in the data{} data object, vm must do some processing on the passed in data{} data object when the Vue instance is created. The processing is to convert the attributes in the data{} data object into virtual attributes controlled by getter and setter methods, and save them in the proxy data object obj and return them.

However, in order to prevent users from directly modifying the original data{} attributes, the entity attributes of the original data{} object are also changed. The names of the added virtual attributes are the same as the entity attribute names, so the original actual attributes will be overwritten by the virtual attributes. When users modify the attribute values, they modify the virtual attributes through the getter and setter methods. In this way, any changes to all properties of the data{} data object will be detected by the Vue instance vm.

let myData = {n:0}
let data = proxy({ data:myData }) // Similar to let vm = new Vue({data: myData})

function proxy({data}/* deconstruction assignment*/){
  let _n = data.n
  Object.defineProperty(data, 'n', { //Overwrite the original data.n property get(){
      return _n
    },
    set(newValue){
      if(newValue<0)return
      _n = newValue
    }
  })// Change the data{} data object's own attributes. The closure can be used to form a context so that the original actual attribute value exists in the closure's context_n const obj = {}
  Object.defineProperty(obj, 'n', {
    get(){
      return data.n
    },
    set(value){
      data.n = value
    }
  }) //Add a proxy for the data{} data object and operate on the data{} data object return obj // obj is the proxy for data{}}

4. Vue’s data responsiveness

The so-called responsiveness means that when things change, they will respond accordingly.

The data in Vue is responsive. Vue uses the Object.defineProperty() function to proxy and monitor the data using getter and setter methods. Once the data changes, Vue will change the UI view corresponding to the data. This is Vue's data responsiveness.

However, Vue uses Object.defineProperty to set the listener, so it can only set the listener for the properties that already exist in the data object when Vue is instantiated, and it does not listen for the properties that do not exist or are added later.

To solve this problem, there are two approaches:

1. Declare all properties in advance

2. Use Vue.set and this.$set to add properties

Using Vue.set and this.$set to add properties will notify Vue to set listening operations for the properties added later.

Vue.set('this.data','m','10')
this.$set('this.data','m','10') //Add attribute m value to vm's data object with value 10

3. Array mutation

When adding data to an array, the number of new additions cannot be controlled, so all data values ​​cannot be declared in advance, and setting them one by one is too troublesome. In addition, the array is one of the commonly used object data types. Therefore, the author of Vue has tampered with the array addition and deletion functions such as push and pop. When users use Vue to add and delete arrays, they still use push and pop, but additional processing is performed inside. These tampered APIs will monitor the data proxy for the addition of the array and change the UI view according to the data response.

The above is the detailed content of in-depth understanding of Vue's data responsiveness. For more information about Vue's data responsiveness, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Detailed explanation of the array of Vue data responsiveness principle
  • Vue data responsiveness summary
  • Detailed explanation of the data responsiveness principle of Vue
  • Summary of knowledge points about Vue data responsiveness principle
  • How is Vue data responsiveness implemented?
  • A brief discussion on the principle of Vue data responsiveness
  • Vue explains the principle of data responsiveness in depth

<<:  Solution to the problem that MySQL can be started when installed in WAMP but cannot be started after restart

>>:  Things about installing Homebrew on Mac

Recommend

Introduction to generating Kubernetes certificates using OpenSSL

Kubernetes supports three types of authentication...

Rounding operation of datetime field in MySQL

Table of contents Preface 1. Background 2. Simula...

CSS Sticky Footer Implementation Code

This article introduces the CSS Sticky Footer imp...

Use momentJs to make a countdown component (example code)

Today I'd like to introduce a countdown made ...

Detailed explanation of nodejs built-in modules

Table of contents Overview 1. Path module 2. Unti...

Vue implements adding watermark to uploaded pictures

This article shares the specific implementation c...

The implementation process of ECharts multi-chart linkage function

When there is a lot of data to be displayed, the ...

How to restore data using binlog in mysql5.7

Step 1: Ensure that MySQL has binlog enabled show...

Solution to the problem of passing values ​​between html pages

The first time I used the essay, I felt quite awkw...

HTML+CSS to achieve charging water drop fusion special effects code

Table of contents Preface: accomplish: Summarize:...

js to achieve image fade-in and fade-out effect

This article shares the specific code of js to ac...