2

从文档(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 中,但在我开始在该字段中输入时它就会出现。

那么,什么给了?

4

1 回答 1

1

从上面的文档链接:

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

换句话说,在组件实例上定义的一切都是反应式的。这允许watcher实例更新所有依赖值和虚拟 DOM。

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

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

于 2018-11-01T19:10:07.410 回答