Основная команда Vue.js уже обсудила изменения, которые будут реализованы в Vue 3. Хотя API не будет меняться, механизм реактивности будет другим. Что это значит, и что это значит для вас?

Реактивность Vue 2

Реактивность в Vue.js достигается с помощью геттеров и сеттеров, как определено в методе Object.defineProperty. Давайте сделаем разбавленную версию того, что происходит во Vue.

Object.defineProperty(obj, key, {    
    enumerable: true,
    configurable: true,
    get:function(){
       return value;
    },
    set:function(newValue){
        if(value !== newValue){
           value = newValue;
           tellTheWorldIhaveChanged(); //somebody is watching!
        }
    }
});

Используя этот тип настройки, каждый раз, когда мы вносим изменение в свойство, он уведомляет наблюдателей и зависимости, которые должны знать, что произошло изменение. Эта настройка свойств происходит при инициализации нашей модели и когда мы явно вызываем Vue.set / vm. $ Set.

Однако при такой настройке требуется дополнительная помощь:

  1. Обновления массивов по индексу
data(){
  return {
    names:[]
  }
}
...
this.persons[0] = 'John Elway';

Вы, вероятно, знаете, что это не приведет к обновлению. Фактически, священное руководство по Vue явно упоминает предостережения в отношении массивов. Почему это так? Поскольку сеттеры в массивах не имеют средств обнаружения назначений по индексу.

Один из вариантов справиться с этим - использовать Vue.set

Vue.set(this.names, 0, 'John Elway');

Однако Vue любезно предоставил нам несколько методов массива, чтобы мы могли обновлять наши массивы, используя эти методы массива.

this.names.push('John Elway');

2. Динамическое добавление свойств

data(){
  return {
    names:[]
  }
}
...
this.$data.lastAddedName = 'John Elway';

Не лучший пример, правда? Я, наверное, уже должен был знать, что это свойство будет существовать, но есть случаи, когда мы могли не знать имя свойства. Отсутствие типизации позволяет нам легко добавлять свойства. Однако реактивность Vue не указывает на то, что мы добавили это свойство.

Я пришел, чтобы спасти положение! - Vue.set

Vue.set(this.$data,'lastAddedName','John Elway');

Если бы только у нас был способ избежать всего этого использования Vue.set и вернуть себе индексы массива.

Реактивность Vue 3

Добро пожаловать в мир реактивности через прокси. Прокси-серверы - это функция, представленная в ES6 AKA ES2015 AKA, они отсутствовали некоторое время. Из-за этого, я уверен, вы узнали о них, но, возможно, не смогли использовать их в производственной среде, потому что они неподражаемы. Нет полифиллов и нет возможности подделать их в старых браузерах.

К счастью, синтаксис не абсурдный. На самом деле это несколько знакомо.

let data = {
   names:[]
};
data.names = new Proxy(data.names,{
    set:function(obj, prop, value){
            if(obj[prop] !== value){
                obj[prop] = value;
                tellTheWorldIhaveChanged();
            }
        }
});

Этот прокси-сервер не только уловит размещение индексированного массива, о котором мы упоминали ранее, но он также сработает при вызове методов массива. Обертки не нужны.

А как насчет динамического добавления свойств?

data = new Proxy(data,{
    set:function(obj, prop, value){
            if(obj[prop] !== value){
                obj[prop] = value;
                tellTheWorldIhaveChanged();
            }
        }
});
data.lastAddedName = 'John Elway'; //tellTheWorldIhaveChanged()

OMG, это так здорово. Давайте создадим петицию на Change.org для скорейшего выпуска!

Резюме

Я набираю это незадолго до релиза 2.5. О Vue 3 не так много говорили, но я с нетерпением жду этого из-за изменений, упомянутых выше. При этом я не смогу использовать его в рабочих проектах в ближайшем будущем. Почему? Vue 3 нельзя использовать с Internet Explorer, и Babel не сможет это исправить.

Однако у этого переписывания есть несколько долгосрочных преимуществ.

  1. Упрощение источника - это переписывание позволяет команде исключить обертки функций массива и уменьшить количество выполняемых проверок типов.
  2. Новичкам легче учиться - устранение недостатков реактивности поможет новичкам в Vue. Это устранит целый класс проблем на форумах.
  3. Лучшая производительность * - я видел, как некоторые люди предполагали, что это ускорит систему реактивности. Это уже довольно быстро, и я еще не совсем уверен в этом

Спасибо за прочтение! Если вы заметите какие-либо ошибки, дайте мне знать.

Обновить

Похоже, что версия, использующая прокси, будет добавлять -next (например, esnext) к текущей версии вместо «Vue 3». Это обновление может появиться уже в Vue 2.6. Итак, когда это выйдет, будет дистрибутив для Vue 2.6 и Vue 2.6-next. Это должно устранить путаницу в том, что доступно в API.

Денни Хедрик любит работать с VueJS и писать о нем. Вы можете следить за ним в Twitter @dennythecoder. Если вам понравилась статья, комментируйте, делитесь с другими или спокойно улыбайтесь. Если вам это не понравилось, оставьте комментарий!

Веб-разработчики и Vue.js чертовски забавны

Найди свой смысл в технологиях