未在数据对象中定义时VueJS变量值不会更新

时间:2018-07-06 02:45:45

标签: javascript html vue.js

我有问题。当我未在Vue实例的数据中定义变量a时,它不会更新以匹配新值。

<div id="app">
  <p>{{ a }}</p><br>
  <input type="text" v-model="a">
</div>

new Vue({
  el: "#app",
  data: {
  },
})

但是当我在数据中使用form时,它可以工作。为什么会有这样的区别?

<div id="app">
  <p>{{ form.a }}</p><br>
  <input type="text" v-model="form.a">
</div>

new Vue({
  el: "#app",
  data: {
    form:[]
  },
})

此外,在同时使用aform的情况下,当我更改输入a时,不会更新text元素。当我更改输入form.a时,两个文本元素aform.a都会更新。有人可以解释这种行为吗?

<div id="app">
  <p>{{ a }}</p><br>
  <input type="text" v-model="a">
  <p>{{ form.a }}</p><br>
  <input type="text" v-model="form.a">
</div>

new Vue({
  el: "#app",
  data: {
    form:[]
  },
})

我的示例:https://jsfiddle.net/0g8npdev/6/

3 个答案:

答案 0 :(得分:4)

a未更新的原因是因为它没有反应。

在vuejs文档中,有关反应性的文章很好:https://vuejs.org/v2/guide/reactivity.html

它说:

  

更改检测警告

     

由于现代JavaScript的局限性(以及   Object.observe),Vue无法检测到属性的添加或删除。   由于Vue在   实例初始化, 属性必须存在于数据对象中   为了让Vue转换并使其具有反应性


回到您的问题:

让我们看看如何在Vue中完成渲染。

首先,它为数据对象中的所有属性定义getter和setter(使用defineProperty方法)。因此,每次更改模型(即aform)时,都会调用setter方法,该方法将通知观察者以呈现更改。

但是,由于数据对象中没有属性a,因此vue不会为其定义任何setter。因此,当您更新输入值时,无法将更改通知给观察者。 (意味着,dom将不会更新)。

现在,form模型也发生了同样的事情。但是由于您已经在数据对象中定义了它,所以vue将为其添加getter和setter方法。因此,当您使用form模型更新输入框时,它将通知观察者重新呈现更改。

这就是为什么仅在更改a时呈现form.a的更改的原因:)

这是我可以为这种行为做的最基本的解释。希望清楚。随时询问您是否有任何疑问。

这篇文章可能会帮助您:https://medium.com/@koheimikami/understanding-rendering-process-with-virtual-dom-in-vue-js-a6e602811782

答案 1 :(得分:1)

如果希望进行双向数据绑定,则应在Vue实例的数据对象中声明变量a

<div id="app">
  <p>{{ a }}</p><br>
  <input type="text" v-model="a">
</div>
new Vue({
  el: "#app",
  data: {
    a: ''
  },
})

答案 2 :(得分:1)

如果您需要代码,请参考@iridescent的答案。

行为说明:

Vue的核心是反应性。如vue文档中所述,当您将JS对象放入data选项时会出现这种情况。

  

将纯JavaScript对象作为数据传递给Vue实例时   选项,Vue将遍历其所有属性并将其转换   使用Object.defineProperty获取/设置。

所以首先要考虑的是,如果您不将a放在数据选项中,它将不会是被动的,并且因为您已经将form放在数据选项中,因此使form.a为react(Vue会将属性'a'转换为setter / getter)。

现在,为什么在jsfiddle link中更新a时仅更新form.a

由于form是反应性的,因此form.a也是反应性的,因此,无论何时更新任何反应性属性,Vue都会更新虚拟Dom,然后将其反映在{{1}中的实际dom中}。简而言之,nextTick()在内存中被更新,但是由于它没有反应性而没有反映在dom中,但是随着a(反应性属性)被更新,virtualdom会获取更改并进行更新。因此,与form.a一起,form.a的当前值也会被更新。这就是预期的行为。

我建议您阅读深度文档here中的反应性

希望对您有帮助。