Vue реактивный ---- метод мутации массива

внешний интерфейс JavaScript Vue.js внешний фреймворк

предисловие

Много начального использованияVueСтуденты обнаружат, что при изменении значения массива значение действительно меняется, но вид остается безразличным.Это потому, что массив слишком холодный?
Проверитьофициальная документацияЯ только что узнал, что дело не в том, что богиня слишком холодна, а в том, что ты использовал неправильный метод.

Кажется, если вы хотите, чтобы богиня двигалась сама по себе, ключ в том, чтобы использовать правильный метод. Хотя метод был указан в официальной документации, мне действительно любопытно.Если вы хотите разблокировать больше поз, вы должны сначала углубиться в сердце богини, поэтому у вас есть идея изучить принцип отклика Vue . (Если вы готовы чистить мое сердце слой за слоем. Вы обнаружите, вы будете поражены... Пристрастился к Гуйкуланхао, Не может выпутаться из QAQ).

подсказки переднего ряда,VueПринцип отзывчивости в основном использует ES5Object.defineProperty, неосведомленные учащиеся могут просматриватьРелевантная информация.

Почему массив не отвечает?

Хорошо подумай,VueОтвет основан наObject.defineProperyДа, этот метод в основном предназначен для изменения описания свойств объекта. Массивы на самом деле являются объектами.Определяя свойства массива, он также должен иметь возможность производить отзывчивый эффект. Сначала проверьте свои мысли, засучите рукава и приступайте к работе.

const arr = [1,2,3];

let val = arr[0];

Object.defineProperty(arr,'0',{
    enumerable: true,
    configurable: true,
    get(){
        doSomething();
        return val;
    },
    set(a){
        val = a;
        doSomething();
    }
});

function doSomething() {

}

Затем войдите в консоль соответственноarr,arr[0] = 2,arr, вы можете увидеть результаты на следующем рисунке.


Эй, все, как и ожидалось.
Далее, увидев этот код, у некоторых учащихся могут возникнуть сомнения, почемуget()метод не возвращает напрямуюthis[0]Шерстяная ткань? но с помощьюvalвернуть значение?
Подумай об этом, черт возьми! ! ! Ты думаешь, это почти бесконечный цикл,get()сам должен получить значение текущего атрибута, вget()вызыватьthis[0]не эквивалентно повторному вызовуget()метод? Это так страшно, так страшно, это пугает рабочих до смерти.

Хотя богиня в вашем воображении может иметь эту позу, богиня перед вами на самом деле не в этой позе.Как может кто-то вроде меня с выставленными атрибутами диаоси догадаться о разуме богини? Почему бы не реагировать на такие данные? Возможно, поскольку массивы и объекты по-прежнему различаются, определение свойств массивов может привести к некоторымПроблема с ошибкой. Или, может быть, это связано с тем, что в процессе взаимодействия может генерироваться большое количество данных, что приводит к общемупадение производительности. Также возможно, что автор может использовать другие методы для достижения эффекта ответа данных после взвешивания за и против. Во всяком случае, я не могу предположить.

Почему я могу ответить, вызвав собственный метод массива?

Зачем использовать методы этих массивов, чтобы заставить данные реагировать?
Давайте посмотрим на исходный код массива.

Проще говоря,defРоль состоит в том, чтобы переопределить свойства объектаvalueстоимость.

//array.js
import { def } from '../util/index'

const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto)
//arrayMethods是对数组的原型对象的拷贝,
//在之后会将该对象里的特定方法进行变异后替换正常的数组原型对象
/**
 * Intercept mutating methods and emit events
 */
[
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
]
.forEach(function (method) {
  // cache original method
  //将上面的方法保存到original中
  const original = arrayProto[method]
  def(arrayMethods, method, function mutator (...args) {
    const result = original.apply(this, args)
    const ob = this.__ob__
    let inserted
    switch (method) {
      case 'push':
      case 'unshift':
        inserted = args
        break
      case 'splice':
        inserted = args.slice(2)
        break
    }
    if (inserted) ob.observeArray(inserted)
    // notify change
    ob.dep.notify()
    return result
  })
})

опубликованоdefчасть кода

/**
 * Define a property.
 */
export function def (obj: Object, key: string, val: any, enumerable?: boolean) {
  Object.defineProperty(obj, key, {
    value: val,
    enumerable: !!enumerable,
    writable: true,
    configurable: true
  })
}

array.js должен изменить некоторые методы массива, мы начинаем сpushметод в качестве примера.
Первый заключается в использованииoriginal = arrayProto['push']чтобы сохранить оригиналpushметод.

Затем пришло время определить метод мутации, дляdefфункция, если не вникать в нее,def(arrayMethods,method,function(){}), эта функция может быть грубо выражена какarrayMethods[method] = function mutator(){};
предположим позвонить послеpushметод, который на самом деле вызываетmutatorметод, вmutatorметод, первое, что нужно сделать, это вызвать сохранение нативногоpushметодoriginal, сначала найдите фактическое значение.
Куча текста выглядит очень абстрактно, поэтому напишите низкоуровневую версию кода, чтобы выразить смысл исходного кода.

const push = Array.prototype.push;

Array.prototype.push = function mutator (...arg){
    const result = push.apply(this,arg);
    doSomething();
    return result
}

function doSomething(){
    console.log('do something');
}

const arr = [];
arr.push(1);
arr.push(2);
arr.push(3);

Просмотрите результат в консоли как:

.

Затем в исходном коде

const ob = this.__ob__
    let inserted
    switch (method) {
      case 'push':
      case 'unshift':
        inserted = args
        break
      case 'splice':
        inserted = args.slice(2)
        break
    }
    if (inserted) ob.observeArray(inserted)
    // notify change
    ob.dep.notify()

Этот код соответствуетdoSomething()охватывать

В этом коде четко написан комментарий из 2 словnotify change, Если вы не знаете этих двух слов, просто посмотрите на Baidu, я сделаю это для вас здесь Значение этих двух слов:опубликовать изменения!
При каждом вызове этого метода будет вычисляться значение, а затем будут выполняться какие-то другие действия, такие как публикация изменений и наблюдение за новыми элементами.Другие процессы ответа в этой статье обсуждаться не будут.

[
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
]

В настоящее время существует так много методов, что если вы используете правильный метод, вы можете изменить позу богини!

резюме

Для заголовка я снова изменился, я начал анализировать принцип ответ Vue, но позже я увидел этот заголовок, то я начну с массива, и эта книга не будет тратить слишком много. Перейти к читать несколько раз. Если эта статья имеет ошибку, вводить в заблуждение других, пожалуйста, укажите, очень благодарна.
Наконец, я желаю всем счастливого Дня холостяков перед Днем холостяков.
Я? Конечно, я не одинокая собака!

Ха-ха-ха-ха-ха-ха-ха-ха-ха-ха-ха-ха-ха-ха-ха-ха-ха-ха
Ох ох ох ох ох ох ох