Vue-添加的嵌套属性会变得活跃,但为什么呢?

时间:2018-11-01 18:51:10

标签: vue.js ruby-on-rails-5 vue-reactivity

根据文档(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的{​​{1}}和reactive setter。该属性最初不在Vue控制台devtool中,但在我开始在该字段中输入后便会出现。

那有什么作用?

1 个答案:

答案 0 :(得分:0)

通过上面的文档链接:

  

当您将纯JavaScript对象作为数据选项传递给Vue实例时,Vue将遍历其所有属性,并使用Object.defineProperty将它们转换为getter / setter。

换句话说,在组件实例上定义的所有内容都是反应性的。这允许watcher实例更新所有相关值和虚拟DOM。

$set方法用于确保反应性适用于深度嵌套的对象/数组或以前未定义的属性。

此外,v-model指令使用$set方法来更新值,因此,即使值最初没有getter和setter,也将在值更新后添加这些值。