Vue Реактивность: Почему замена свойства (массива) объекта не запускает обновление - PullRequest
0 голосов
/ 29 мая 2020

У меня есть приложение Vue, в котором я пытаюсь сделать тонкую оболочку над API Mapbox. У меня есть компонент с некоторыми простыми гео json данными, и когда эти данные обновляются, я хочу вызвать функцию рендеринга на карте, чтобы обновить карту этими новыми данными. Наблюдатель Vue должен быть в состоянии выполнить sh это. Однако мой наблюдатель не вызывается при изменении данных, и я подозреваю, что это один из случаев, когда vue реактивность не может уловить. Я знаю, что могу легко решить эту проблему с помощью this.$set, но мне любопытно, почему это не реактивное обновление, хотя, согласно моему пониманию правил, оно должно быть. Вот соответствующая модель данных:

data() {
  return{
    activeDestinationData: {
      type: "FeatureCollection",
      features: []
    }
  }
}

Затем у меня есть наблюдатель:

watch: {
  activeDestinationData(newValue) {
    console.log("Active destination updated");
    if (this.map && this.map.getSource("activeDestinations")) {
      this.map.getSource("activeDestinations").setData(newValue);
    }
  },
}

Наконец, внизу в моем приложении logi c я полностью обновляю функции на activeDestination. переназначение массива новому массиву с одним элементом:

// Feature is a previously declared single feature
this.activeDestinationData.features = [feature];

По какой-то причине наблюдатель никогда не вызывается. Я читал о некоторых проблемах с реактивностью здесь , но ни один из двух случаев здесь не применим:

Vue не может обнаружить следующие изменения в массиве:

Когда вы напрямую устанавливаете элемент с индексом, например vm.items [indexOfItem] = newValue

Когда вы изменяете длину массива, например vm.items.length = newLength

Что мне здесь не хватает, из-за чего не возникает реактивность? И мой единственный вариант для предполагаемого поведения this.set() или есть более элегантное решение?

Ответы [ 2 ]

2 голосов
/ 29 мая 2020

по умолчанию vue будет выполнять неглубокое сравнение, и, поскольку вы изменяете массив, а не заменяете, его ссылочное значение остается таким же. вам необходимо передать ссылку на новый массив при обновлении его содержимого или передать параметр deep: true, чтобы просмотреть изменения вложенных значений как:

watch: {
  activeDestinationData: {
    handler(newValue) {
      console.log("Active destination updated");
      if (this.map && this.map.getSource("activeDestinations")) {
        this.map.getSource("activeDestinations").setData(newValue);
      }
    },
    deep: true
  }
}
1 голос
/ 29 мая 2020

Если вам нужно наблюдать за глубокой структурой, вы должны написать несколько параметров

watch: {
  activeDestinationData: {
      deep: true,
      handler() { /* code... */ }
}

Вы можете прочитать больше там -> https://vuejs.org/v2/api/#watch Надеюсь, я вам помог :) 1007 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...