【问题标题】:Why Vuejs is not updating model until input loses focus为什么 Vuejs 直到输入失去焦点才更新模型
【发布时间】:2018-07-29 01:05:41
【问题描述】:

我的应用使用以下类型的数据: 有些公司每个都有一个数据点列表。 每个数据点都有一个类型,每个公司只能有一个类型的数据点。

+Company_1  
|  
|--Datapoint_1 : type_1  
|--Datapoint_2 : type_2  
|--Datapoint_3 : type_3  
|  
|  
+Company_2  
|  
|--Datapoint_4 : type_3  
|--Datapoint_5 : type_2  
|  
|+Company_3  
|  
|--Datapoint_6 : type_2  
...  
...  

总共有大约 1000 个数据点和 20 家公司。 该应用程序基于这些数据点计算分析,目标是允许用户操作这些数据点,以便查看给定场景中的结果。 在任何给定时刻,都有“selected_company”和“selected_type”,根据这两个选择,应该选择正确的数据点进行操作。

我意识到如果“公司”变量和“数据点”属性是数组,则必须对所有项目进行搜索才能找到正确的项目。 因此,我选择将它们设为对象:

companies = {
  '1' : {
    name : 'Company_1',
    datapoints : {
      'type_1' : { ... },
      'type_2' : { ... },
      'type_3' : { ... }
    }
  },
  '2' : {...},
  '3' : {...},
  .
  .
  .
}

问题:

我有一个“数据点”组件,我将数据点作为道具传递:

<datum-comp :datum="companies[selected_company].datapoints[selected_type]"></datum-comp>

在这个组件中,我有一个用于操作数据点的 score 属性的输入:

<input v-model.number="datum.score" class="form-control">

但是,此输入表现出非常奇怪的行为。当我输入输入时,模型不会立即更新。相反,Vue 似乎在等待我从输入 (onBlur) 更改焦点,然后再更新模型。

not updating until onblur

更奇怪的是,当我将 datapoints 属性设为数组时

companies = {
      '1' : {
        name : 'Company_1',
        datapoints : [
          { ... },
          { ... },
          { ... }
        ]
      },

并使用一种方法来检索数据点(而不是直接传递它),Vue 以正确的方式运行!

<datum-comp :datum="getDatum(selected_company, selected_type)"></datum-comp>

(在 js 文件中:)

var app = new Vue({
    el : '#app',
    data:{...},
    methods:{
      getDatum: function(selected_company, selected_type){
          var datum = this.companies[selected_company].datapoints.find(function(elem){
            return elem.type == selected_type
          })
          return datun
        }
    }
  })

updating correctly

我需要帮助来理解为什么 Vue 在这些情况下会这样,因为它对应用程序性能有一些严重的影响。 提前致谢。

【问题讨论】:

  • 在同一浏览器中的 Vue.js 文档示例 vuejs.org/v2/guide/forms.html 中是否也会出现相同的行为?您可能想尝试@input="",然后调用一个执行更新的函数。

标签: vue.js vuejs2


【解决方案1】:

v-model 只是syntax sugar for...
:value="modelValue" @input="modelValue = $event.target.value"
正如你所说,它更新了模型oninput,大部分时间都运行良好。

如果你想要别的东西,这很容易做到。只需将更新端更改为onkeypress,所以...

<input  class="form-control
    :value="datum.score" 
    @keypress="datum.score = $event.target.value""
    @input="datum.score = $event.target.value""
>

当您将数据点从数组更改为对象时,您注意到的变化可能是由于 Vue cannot detect changes made in an array using array syntax(方括号)。您需要使用数组方法(push、pop、splice 等)或 Vue.set()。就像你说的,这并不直观,但它是 Vue 中为数不多的陷阱之一。这是由于javascript的限制,文档中有很好的介绍。

【讨论】:

  • 用鼠标拖拽数据到字段会触发吗?
  • 不,只是继续累积你使用的事件,直到你得到你想要的行为。按键和输入的组合应该覆盖它。我会更新答案。
  • 是的。单独的问题。 Changes made to arrays using array syntax do not trigger reactivity。这是 javascript 的一个限制,建议使用一些解决方法。这是 Vue 中为数不多的陷阱之一,文档中有很好的解释。
猜你喜欢
  • 1970-01-01
  • 2016-12-05
  • 2020-04-18
  • 2017-09-17
  • 1970-01-01
  • 2011-07-30
  • 2019-10-21
  • 1970-01-01
  • 2019-02-25
相关资源
最近更新 更多