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 build a SOLO personal blog from scratch using Docker

Table of contents 1. Environmental Preparation 2....

Summary of shell's method for determining whether a variable is empty

How to determine whether a variable is empty in s...

Detailed explanation of how to use zabbix to monitor oracle database

1. Overview Zabbix is ​​a very powerful and most ...

How to change the system language of centos7 to simplified Chinese

illustrate When you install the system yourself, ...

Detailed explanation of concat related functions in MySQL

1. concat() function Function: Concatenate multip...

Tutorial on installing MySQL with Docker and implementing remote connection

Pull the image docker pull mysql View the complet...

HTML optimization speeds up web pages

Obvious HTML, hidden "public script" Th...

Steps to split and compress CSS with webpack and import it with link

Let's take a look at the code file structure ...

How to manually build a new image with docker

This article introduces the method of manually bu...

Linux Operation and Maintenance Basic System Disk Management Tutorial

1. Disk partition: 2. fdisk partition If the disk...

MySQL 5.7.17 latest installation tutorial with pictures and text

mysql-5.7.17-winx64 is the latest version of MySQ...

MySQL master-slave replication principle and points to note

Written in front I have been writing a special to...

Vue+video.js implements video playlist

This article shares the specific code of vue+vide...

Detailed explanation of nginx installation, deployment and usage on Linux

Table of contents 1. Download 2. Deployment 3. Ng...

Implementing carousel effects with JavaScript

This article shares the specific code for JavaScr...