Поддерживает ли Vue реактивность на картах и ​​наборах типов данных?

В документах для Vue.js упоминается интеллектуальное автоматическое отслеживание изменений для простых объектов Javascript:

Когда вы передаете простой объект JavaScript в экземпляр Vue в качестве его параметра данных, Vue.js проведет все его свойства и преобразует их в getter/seters, используя Object.defineProperty.

Так как типы данных Javascript Map и Set предназначены для использования со встроенными методами get/Set, как я могу заставить Vue отслеживать вызовы (и, следовательно, изменения) во внутреннее состояние Map и Set s?

Ответ 1

Vue.js не поддерживает реактивность по типам Map и Set (пока?).

В теге есть обсуждение и эта работа вокруг (пользователем "inca" ):

Наборы и Карты не наблюдаются Vue. Чтобы использовать их - либо в v-for, либо в вычисленных свойствах, методах, наблюдателях, шаблонные выражения и т.д. - вам необходимо создать сериализуемую реплику этой структуры и выставить ее в Vue. Здесь наивный пример, который использует простой счетчик для предоставления Vue информации, что Setобновление:

data() {
  mySetChangeTracker: 1,
  mySet: new Set(),
},

computed: {
  mySetAsList() { 
    // By using `mySetChangeTracker` we tell Vue that this property depends on it,
    // so it gets re-evaluated whenever `mySetChangeTracker` changes
    return this.mySetChangeTracker && Array.from(this.mySet);
  },
},

methods: {
  add(item) {
    this.mySet.add(item);
    // Trigger Vue updates
    this.mySetChangeTracker += 1;
  }
}

Это иллюстрирует своего рода хакерский, но 100% -ный метод работы не наблюдаемые данные реактивны. Тем не менее, в реальных делах я оказался с сериализованными версиями Sets/Maps (например, вы, вероятно, захотите хранить измененные версии наборов/карт в localstorage и, таким образом, сериализуйте их в любом случае), поэтому никаких искусственных счетчиков/хаков не было.

Ответ 2

Насколько я знаю, реактивность Vue отслеживает назначения. Если вы выполняете назначение на своем устройстве, оно должно отслеживать реактивность, например:

methods: {
  add(item) {
    this.mySet = new Set(this.mySet.add(item));
  }
}

Это дает вам более чистый код, но с очевидной проблемой: производительностью.

Просто выберите решение в соответствии с вашими потребностями :)