Vue - Добавленные вложенные атрибуты становятся реактивными, но почему? - PullRequest
0 голосов
/ 01 ноября 2018

Из документации (https://vuejs.org/v2/guide/reactivity.html), у меня сложилось впечатление, что все атрибуты объекта должны быть в объекте данных Vue, чтобы быть реактивными, если они явно не добавлены с использованием Vue.set(object, key, value) или this.$set(object, key, value).

Однако я использую Rails с Vue, и любой атрибут данных, который я собираю в форме, независимо от того, находится он изначально в объекте данных или нет, становится реактивным. Я использую Jbuiler для создания объектов JSON, но я не думаю, что это влияет на реактивность, поскольку, если я удалю атрибуты, они будут реактивными, когда собраны в форме. Я пробовал атрибуты, которые есть на объекте в Rails, и те, которые, в Jbuilder или нет, не добавляются через консоль или нет. Все становятся реактивными. Это замечательно, но я не ожидаю такого поведения, поэтому мне бы хотелось это понять.

Вот пример ...

# Product attributes: name, code (note: not 'location'!) 

# Rails Controller

def new
  @product = Product.new
end


# JS
var product = gon.product // using Gon gem to pass variables

var app = new Vue({
  el: element,
  data: function() {
      return {
      id: id,
      product: product
    } 
  }
)}


# HTML
<div class="col-sm-3">
  <input type="text" v-model="product.code" class="form-control form-control-sm" />
</div>
<div class="col-sm-3">
  <input type="text" v-model="product.location" class="form-control form-control-sm" />
</div>
<div>
  Product Code: {{ product.code }}
  Product Location: {{ product.location }}
</div>

Когда я начинаю печатать в поле product.location, вывод немедленно появляется на экране, поэтому он кажется реактивным. Изучение объекта в консоли выявляет reactive getter и reactive setter для product.location. Атрибут изначально отсутствует в консоли Vue devtool, но появляется, как только я начинаю печатать в поле.

Итак, что дает?

1 Ответ

0 голосов
/ 01 ноября 2018

Из документации по ссылке выше:

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

Другими словами, все, что определено в экземпляре компонента, является реактивным. Это позволяет watcher экземпляру обновлять все зависимые значения и виртуальный DOM.

$ set метод используется, чтобы гарантировать, что реактивность работает для глубоко вложенных объектов / массивов или ранее не определенных свойств.

Кроме того, директива v-model использует метод $ set для обновления значений, поэтому, даже если значение не имело изначально методов получения и установки, они будут добавлены после обновления значения.

...