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

How to solve the phantom read problem in MySQL

Table of contents Preface 1. What is phantom read...

How to sort a row or column in mysql

method: By desc: Neither can be achieved: Method ...

Best way to replace the key in json object

JSON (JavaScript Object Notation, JS Object Notat...

Notes on configuring multiple proxies using vue projects

In the development process of Vue project, for th...

Summary of common MySQL commands

Set change mysqlroot password Enter the MySQL dat...

Detailed example of inserting custom HTML records in Quill editor

It is already 2020. Hungry humans are no longer s...

Why is it not recommended to use index as the key attribute value in Vue?

Table of contents Preface The role of key The rol...

Implementation methods of common CSS3 animations

1. What is CSS Animations is a proposed module fo...

Detailed code examples of seven methods for vertical centering with CSS

When we edit a layout, we usually use horizontal ...

Detailed explanation of the use of CSS pointer-events attribute

In front-end development, we are in direct contac...

Index Skip Scan in MySQL 8.0

Preface MySQL 8.0.13 began to support index skip ...