在改变事件时,Vuejs会获得旧值

mad*_*adi 15 javascript jquery vue.js vuejs2

请参阅下面的我的代码段.如何获得已更改模型的旧值,在这种情况下是vuejs中的年龄?

var app = new Vue({
  el:"#table1",
  data:{
   items:[{name:'long name One',age:21},{name:'long name Two',age:22}]
  },
  methods:{
    changeAge:function(item,event){
      alert(item.age);
    }
  }
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<table class="table table-cart" id="table1">
   <thead>
     <tr>
       <th>Name</th>
       <th>Age</th>
     </tr>
  </thead>
   <tbody>
     <tr v-for="(item,index) in items">
       <td>{{item.name}} :</td>       
       <td>
         <input type="text" name="qty"
                v-model="item.age"   
                @change="changeAge(item,$event)">
       </td>
     </tr>
   </tbody>
 </table>
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用手表,但我无法找到任何帮助来观察一系列物品的年龄.

Fra*_*rax 14

该解决方案假定您仅在处理来自用户输入的更改时才需要旧值,而不是通用模型更改-可能是这种情况。在下面,我添加了一个解决方案的草图,监视是否有必要进行所有更改,尽管也许最好在发生更改的地方而不是在此组件中控制其他更改。

放下v-model并替换为手动处理。

重要的是要注意:“尽管有点神奇,但v模型本质上是用于在用户输入事件上更新数据的语法糖(...)”。因此,就像您几乎已经做过的那样,您可以删除它并直接处理事件,而不会造成太大的伤害。

首先,将替换v-model:value。输入内容仍将遵循item.age更新,但不会自动更新年龄。

<input type="text" name="qty"
       :value="item.age"
       @change="changeAge(item,$event)">
Run Code Online (Sandbox Code Playgroud)

然后,为了实际更新值,将添加item.age = event.target.valuechangeAge,如下所示:

changeAge: function(item, event){
  alert(item.age);  // Old value
  alert(event.target.value);  // New value
  item.age = event.target.value;  // Actual assignment
}
Run Code Online (Sandbox Code Playgroud)

注意:您可能想使用@input,这是v模型实际使用的。

就是这样,它应该可以解决问题。如果需要防止更改,则可以忽略分配,但是需要重置输入值。item.age = item.ageVue.set(item, 'age', item.age)可以做的伎俩,但我不能肯定它会。

注意:event.target.value是字符串,如果需要数字,请使用parseInt()

为每个项目创建一个单独的组件实例并在其中创建手表

万一您需要注意所有更改。但是,如果需要,也许应该在其他地方而不是在此组件中进行。

我还没有准备好所有细节,所以我只准备一份通用草案:在您的地方v-for,而不是简单<input>地放置另一个组件,例如<my-item>。你穿上v-model=item它。在组件内部,您可以创建<input>和转发value道具,以及在外部转发它的input/ change事件。在组件中,单个项目是单个道具,因此您可以将观察者直接连接到它。相关文档:组件基础自定义组件v-model道具


小智 11

可能为时已晚。只要监视对象内的函数名称被命名为被监视的变量,这对我有用。它只监视特定的变量。

watch:{
   items: function(newVal, oldVal){
      console.log("New value: "+ newVal + ", Old value: " + oldVal);
   },
   other_variable: function(newVal, oldVal){
      console.log("New value: "+ newVal + ", Old value: " + oldVal);
   }
}
Run Code Online (Sandbox Code Playgroud)


Sau*_*abh 10

你并没有在变化元件的旧值作为解释在这里.此外,在观察对象时,您无法获得此处所述的旧值,直到对象的引用发生更改为止.

要解决这些问题,您可以创建一个计算属性,它将克隆您的items数据,您可以将一个观察者放在这个计算属性上,以便了解旧值,请参阅下面的工作代码:

var app = new Vue({
  el:"#table1",
  data:{
   items:[{name:'long name One',age:21},{name:'long name Two',age:22}]
  },
  watch:{
    clonedItems: function(newVal, oldVal){
      alert(JSON.stringify(newVal));
      alert(JSON.stringify(oldVal));
    }
  },
  computed:{
    clonedItems: function(){
       return JSON.parse(JSON.stringify(this.items))
    }
  }
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<table class="table table-cart" id="table1">
   <thead>
     <tr>
       <th>Name</th>
       <th>Age</th>
     </tr>
  </thead>
   <tbody>
     <tr v-for="(item,index) in items">
       <td>{{item.name}} :</td>       
       <td>
         <input type="text" name="qty"
                v-model="item.age">
       </td>
     </tr>
   </tbody>
 </table>
Run Code Online (Sandbox Code Playgroud)

  • 这意味着对于所有更改,此事件都将被触发。我只需要 item.age 更改事件发生。您的解决方案很好,但有没有办法使其具体?就像我退格一样,事件也会被触发 (2认同)
  • 事情在计算属性中,我们无法获取当前项目。所以这就是令人困惑的wat。不敢相信 Vue 有这么大的限制 (2认同)

小智 5

将v-model替换为value prop v-model 是双向绑定,它会使您的状态变得复杂,然后在更改事件中手动修改age属性

<input type="text" name="qty"
                :value="item.age"   
                @change="changeAge">



export default {
  change(val) {
     let ov = this.item.age
     let nv = val
     // do something
     // this.item.age = nv
   }
}
Run Code Online (Sandbox Code Playgroud)