This is the 9th day of my participation in Gwen Challenge

One, foreword

The first part mainly introduces the realization of array deep observation, and the core points are as follows:

At first, only the prototype method of array type was rewritten without recursive processing, so only the single-layer array hijacking was realized.

Hijack an array by observing an array recursively. Hijack an array by observing an array recursively

However, since the Observe method does not handle non-object types, the value types in the array will not be hijacked;

In contrast to the vue2.x functionality, the code still needs to do the following:

  • Object, old property changes to object, array – need to modify the value of deep observation processing
  • Object, new attributes – need to be described
  • Array, new object, array, common value case – need to implement the array method rewrite and modify the value of recursive processing

To sum up, it can be divided into two parts:

  • Object data changes: In an object, the old property changes to an object; Object, new attributes;
  • Array data changes: In an object, the old property changes to an array; Array, new objects, arrays, ordinary values;

In this paper, the observation of object data changes (old attributes changed to objects, new attributes)

Since the recursive hijacking of arrays is not yet implemented, this article does not cover the case of changing the old property of an object to an array.

Merge “object old property change to array” and “observation of array data change”;

TODO considers that “the case of an old property changing to an array in an object” should be included in this article “The case of an observed change in object data” for the following reasons: Even if there is no recursive observation for object property modification to array, it should be classified as “object data change”, and this problem will be solved when the “array data” is implemented recursively.


Second, in the object, the old attribute is changed to the object observation problem

let vm = new Vue({
  el: '#app'.data() {
    return { message: 'Hello Vue'.obj: { key: "val" }, arr: [1.2.3]} // data returns an object}});// Change the property message from a normal value to an object type
vm.message = { a: 100 }
// Modify the attributes of the new object
vm.message.a = 200;
Copy the code
// src/observe/index.js#defineReactive

function defineReactive(obj, key, value) {
  observe(value);
  Object.defineProperty(obj, key, {
    get() {
      return value;
    },
    set(newValue) {
      console.log("Modified observed attribute key =" + key + ", newValue = " + JSON.stringify(newValue))
      if (newValue === value) returnvalue = newValue; }})}Copy the code

1, vm.message = {a: 100}

Change the message property of data from the initial value "Hello Vue" to the object type {a: 100} because {a: 100} is a new object added after data initialization. It belongs to the new object within the object. The new object in the current version will not be hijacked, so it will not trigger the update of the viewCopy the code

2, vm.message.a = 200

Because the object {a: 100} is not being observed, modifying properties in this object does not trigger an update to the viewCopy the code

Third, in the object, the old property is changed to the object observation implementation

In order to realize the data observation of the newly added object, when the value is set to object, the object can be continued for deep observation.

// src/observe/index.js#defineReactive

/** * Redefine attributes in the data Object using Object.defineProperty. Vue2's performance bottleneck is also here due to object. defineProperty's low performance@param {*} Obj needs to define the object * for attributes@param {*} Key Specifies the name of the property defined for the object@param {*} Value Specifies the attribute value */ defined for the object
function defineReactive(obj, key, value) {
  observe(value);// Implement deep observation recursively
  Object.defineProperty(obj, key, {
    get() {
      return value;
    },
    set(newValue) {
      console.log("Modified observed attribute key =" + key + ", newValue = " + JSON.stringify(newValue))
      if (newValue === value) return
      Observe observe observe observe observe observe observe observe observe observe observe observe observeobserve(newValue); value = newValue; }})}Copy the code

Output result:

In this way, the deep observation of the new object in the object is realized

At the same time, the view can be updated through data hijacking when the properties in the new object are changed again


Fourth, in the object, the situation of new attributes

Add a nonexistent attribute B to the new object {a: 100} of the message attribute. Will data hijacking occur?

let vm = new Vue({
  el: '#app'.data() {
    return { message: 'Hello Vue'.obj: { key: "val" }, arr: [1.2.3]}}});// The property message is changed from "normal value" to "object" type
vm.message = { a: 100 }
// Add a nonexistent attribute to the new object
vm.message.b = 200;
// Modify the value of the new attribute
vm.message.b = 300;
Copy the code
Adding a new attribute b to a new object will not be hijacked or trigger any logic for data hijacking. Therefore, adding a new attribute to a new object will not be hijacked.Copy the code

In ve2. X, adding new attributes to new objects also does not implement data hijacking;

But you can use vm.$set to realize the data observation capability of the new attributes in the object;


Five, the end

This paper mainly introduces the observation of array data changes:

  • The deep observation processing is realized when the old attribute value of object is changed to object or array.
  • Combined with the realization principle, the reason why the new attributes of the object cannot be observed is explained, and how to realize the data observation.

Next, the observation of array data changes (in an object, the old property changes to an array; Array, new object, array, normal value;)