How to monitor array changes in Vue

How to monitor array changes in Vue

Preface

Some time ago, I learned about the principles of responsive data in Vue (and took notes on the responsive principles of Vue). In fact, it is a responsive design that controls getters and setters through Object.defineProperty and uses the observer mode. Then the array has a series of operation methods, which do not trigger the array's getter and setter methods. So how is the responsive design for arrays implemented in Vue? Let's learn it together.

Source code

https://github.com/vuejs/vue/blob/dev/src/core/observer/array.js

Where do I start my first step in learning?

Emmmm...
I think we should first clarify the principle of data responsiveness in Vue, so that it will be better to understand how to detect array changes in Vue. Therefore, you can find the article online and read it with the source code. I believe you will understand it. Let me recommend a blog I read before, as well as the learning record I wrote after reading it, haha.

Vue responsive principle

The principle and implementation of two-way binding in Vue

Okay, let's take a look at this first. Ha ha!

Start with a picture

Let's take a look at the picture below and understand the idea of ​​​​implementation in Vue first, so that when we look at the implementation of the source code later, it will be clear and understandable.

Look at this picture and think about it. Do you have a general understanding?

First determine whether the browser supports the __proto__ pointer

Rewrite these 7 methods of the array, and then point the rewritten array to the prototype of the array depending on whether __proto__ is supported.

Isn’t it simple! ! !

Look at the source code

Now that we understand the implementation principle, let's take a look at the source code. The main purpose of looking at the source code is to have a deeper understanding of how the author implemented it. You can also look at excellent code encoding methods and learn from them.

I've written some explanations in the code block below!

//https://github.com/vuejs/vue/blob/dev/src/core/observer/array.js


//The def method is a layer of method based on Object.defineProperty encapsulation. It is very simple. I will post the code below to avoid you having to look for it.
import { def } from '../util/index' 

//Save the native array prototype object const arrayProto = Array.prototype

// Make a prototype connection and point the prototype of arrayMethods to Array.prototype
export const arrayMethods = Object.create(arrayProto)

const methodsToPatch = [
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
]

methodsToPatch.forEach(function (method) {
  // Cache native method const original = arrayProto[method]
  def(arrayMethods, method, function mutator (...args) {
    var args = [], 
    len = arguments.length;
    while (len--) args[len] = arguments[len];
    const result = original.apply(this, args) // The original array method execution result const ob = this.__ob__ // This __ob__ is an instance of Observe~~~~
    let inserted
    switch (method) {
      case 'push':
      case 'unshift':
        inserted = args
        break
      case 'splice':
        inserted = args.slice(2)
        break
    }
    if (inserted) ob.observeArray(inserted) // If the array changes, call observeArray again
    // notify change
    ob.dep.notify() //
    return result
  })
})

This is the code for Observer:

var Observer = function Observer(value) {
    this.value = value;
    this.dep = new Dep();
    this.vmCount = 0;
    def(value, '__ob__', this); //Here you can see that an Observe instance is bound to each object data, so this.__ob__ in the above code is this if (Array.isArray(value)) { // Here we determine whether it is an array type of data, if so, observeArray is used
      if (hasProto) {
        protoAugment(value, arrayMethods);
      } else {
        copyAugment(value, arrayMethods, arrayKeys);
      }
      this.observeArray(value); //Here is to process array type data, as follows} else {
      this.walk(value);
    }
  };

The following is the implementation of observeArray:

Observer.prototype.observeArray = function observeArray(items) {
    for (var i = 0, l = items.length; i < l; i++) {
      observe(items[i]); // The observe method is as follows}
  };

Here we look at the observe method:

function observe(value, asRootData) {
    if (!isObject(value) || value instanceof VNode) {
      return
    }
    var ob;
    if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
      ob = value.__ob__;
    } else if (
      shouldObserve &&
      !isServerRendering() &&
      (Array.isArray(value) || isPlainObject(value)) &&
      Object.isExtensible(value) &&
      !value._isVue
    ) {
      ob = new Observer(value);
    }
    if (asRootData && ob) {
      ob.vmCount++;
    }
    return ob
  }

This is about the implementation of the def method. It’s very simple so I won’t explain it:

function def (obj, key, val, enumerable) {
    Object.defineProperty(obj, key, {
      value: val,
      enumerable: !!enumerable,
      writable: true,
      configurable: true
    });
}

The above is the details about how to monitor array changes in Vue. For more information about how Vue monitors arrays, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • How to monitor array changes in Vue
  • Vue development watch monitoring array, object, variable operation analysis
  • Vue monitors array changes source code analysis
  • Vue mobile phone physical monitoring key + exit prompt code
  • Vue deep monitoring (monitoring changes in objects and arrays) and immediate execution of monitoring examples
  • Vue parent component monitors child component life cycle
  • Vue implements listening to window closing events and sending requests before the window closes
  • Vue monitors the change operation of Treeselect selection
  • Vue listens to route changes and refreshes the page in the App.vue file

<<:  How to start tomcat using jsvc (run as a normal user)

>>:  (MariaDB) Comprehensive explanation of MySQL data types and storage mechanisms

Recommend

Use pure JS to achieve the secondary menu effect

This article example shares the specific code of ...

XHTML: Frame structure tag

Frame structure tag <frameset></frameset...

React event binding details

Table of contents Class component event binding F...

Practice of using SuperMap in Vue

Table of contents Preface Related Materials Vue p...

HTML background color gradient achieved through CSS

Effect screenshots: Implementation code: Copy code...

Mysql auto-increment primary key id is not processed in this way

Mysql auto-increment primary key id does not incr...

Specific method of viewing user authorization information in mysql

Specific method: 1. Open Command Prompt 2. Enter ...

Summary of the execution issues between mysql max and where

Execution problem between mysql max and where Exe...

JavaScript flow control (branching)

Table of contents 1. Process Control 2. Sequentia...

A brief analysis of MySQL backup and recovery

Table of contents 1. Introduction 2. Simple defin...

Summarize the commonly used nth-child selectors

Preface In front-end programming, we often use th...

MySQL scheduled task implementation and usage examples

This article uses examples to illustrate the impl...

Introduction to deploying selenium crawler program under Linux system

Table of contents Preface 1. What is selenium? 2....

Analyzing the MySql CURRENT_TIMESTAMP function by example

When creating a time field DEFAULT CURRENT_TIMEST...