Vue - добавленные вложенные атрибуты становятся реактивными, но почему?

Из документации (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, но он появляется, как только я начинаю вводить текст в поле.

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


person Travis Smith    schedule 01.11.2018    source источник
comment
как gon.product изначально выглядит?   -  person Roy J    schedule 01.11.2018


Ответы (1)


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

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

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

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

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

person aBiscuit    schedule 01.11.2018