Javascript Vuejs在发生更改事件时获取旧值

Javascript Vuejs在发生更改事件时获取旧值,javascript,jquery,vuejs2,vue.js,Javascript,Jquery,Vuejs2,Vue.js,请参考我下面的片段。如何获取更改模型的旧值,在本例中是vuejs中的年龄 var-app=新的Vue({ el:“表1”, 数据:{ 项目:[{姓名:'long name One',年龄:21},{姓名:'long name Two',年龄:22}] }, 方法:{ 变更:功能(项目、事件){ 警惕(项目、年龄); } } }); 名称 年龄 {{item.name}}: 如前所述,您不会在更改时获得元素的旧值。此外,在观察对象时,除非对象的引用发生更改,否则无法获得所解释的旧值 要解决这些

请参考我下面的片段。如何获取更改模型的旧值,在本例中是vuejs中的年龄

var-app=新的Vue({
el:“表1”,
数据:{
项目:[{姓名:'long name One',年龄:21},{姓名:'long name Two',年龄:22}]
},
方法:{
变更:功能(项目、事件){
警惕(项目、年龄);
}
}
});

名称
年龄
{{item.name}}:

如前所述,您不会在更改时获得元素的旧值。此外,在观察对象时,除非对象的引用发生更改,否则无法获得所解释的旧值

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

var-app=新的Vue({
el:“表1”,
数据:{
项目:[{姓名:'long name One',年龄:21},{姓名:'long name Two',年龄:22}]
},
观察:{
clonedItems:函数(newVal、oldVal){
警报(JSON.stringify(newVal));
警报(JSON.stringify(oldVal));
}
},
计算:{
clonedItems:function(){
返回JSON.parse(JSON.stringify(this.items))
}
}
});

名称
年龄
{{item.name}}:

可能太晚了。只要watch对象中的函数名被命名为被监视的变量,这对我来说就行了。它只监视特定的变量

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);
   }
}
此解决方案假设您仅在处理来自用户输入的更改时才需要旧的值,这可能是实际情况,而不是一般的模型更改。在下面,我添加了一个解决方案的草图,如果有必要,可以查看中的所有更改,不过最好是在发生更改的位置控制其他更改,而不是在该组件中

放下
v型
,用手动操作代替。 值得注意的是。因此,在不造成太大伤害的情况下,您可以删除它并直接处理事件,就像您几乎已经做过的那样

首先,将
v型
替换为
:value
。输入仍将跟随
项。年龄更新,但不会自动更新年龄

<input type="text" name="qty"
       :value="item.age"
       @change="changeAge(item,$event)">
注意:您可能希望使用@input,这是v-model实际使用的

就这样,它应该会起作用。如果需要防止更改,可以省略赋值,但是需要重置输入值
item.age=item.age
Vue.set(item'age',item.age)

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

为每个项目创建一个单独的组件实例,并在其中创建一个手表 以防你需要观察所有的变化。然而,如果您需要它,也许您应该在其他地方做,而不是在这个组件中


我还没有准备好所有的细节,所以我只准备了一般的草稿:在您的
v-for
中,而不是普通的
,放置另一个组件,比如
。你把
v-model=item
放在上面。在组件内部,您创建
并将
道具转发给它,以及将其
输入
/
更改
事件转发到外部。在您的组件中,单个项目是单个道具,因此您可以将观察者直接附加到它。相关文件:,.

值替换v型 v-model是双向绑定的,它将使您的状态变得复杂 然后在更改事件中手动修改年龄属性

<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
   }
}

导出默认值{
更改(val){
设ov=this.item.age
设nv=val
//做点什么
//this.item.age=nv
}
}
您只需使用

<input type="text" name="qty" v-model="item.age" @change="changeAge($event)">
在vue方法对象中

changeAge(){
这个.$nextTick(()=>{
//在这里设置当前值,执行所需操作
})
}

我也有同样的问题。我通过在Vue组件中包装输入并在包装器组件中查看属性来解决这个问题。在watcher中,我调用$emit,将新值、旧值和项作为参数传递

<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>
                <item-age-input
                    :item="item"
                    @age-changed="ageChanged"></item-age-input>
            </td>
        </tr>
    </tbody>
</table>

<script>
Vue.component('item-age-input', {
    props: {
        item: {
            type: Object,
            required: true
        }
    },
    template: `<input type="text" name="qty" v-model="item.age">`,
    watch: {
        "item.age": function(newAge, oldAge) {
            this.$emit('age-changed', newAge, oldAge, this.item);
        }
    }
});

var app = new Vue({
    el:"#table1",
    data:{
        items:[{name:'long name One',age:21},{name:'long name Two',age:22}]
    },
    methods: {
        ageChanged: function(newAge, oldAge, item){
            alert(newAge + ', ' + oldAge);
            console.log(item);
        }
    }
});
</script>

名称
年龄
{{item.name}}:
Vue.组件('item-age-input'{
道具:{
项目:{
类型:对象,
必填项:true
}
},
模板:``,
观察:{
“项目年龄”:功能(新年龄、老年){
此.$emit('age-changed',newAge,oldAge,this.item);
}
}
});
var app=新的Vue({
el:“表1”,
数据:{
项目:[{姓名:'long name One',年龄:21},{姓名:'long name Two',年龄:22}]
},
方法:{
年龄更改:功能(新年龄、旧年龄、项目){
警觉(新年龄+','+老年人);
控制台日志(项目);
}
}
});

这意味着对于所有更改,将触发此事件。我只需要发生item.age更改事件。您的解决方案很好,但有没有办法使其具体化?就像我退格一样,事件正在被触发also@madi一种选择是拥有一个返回年龄的computed属性,并在其上拥有watcher。这就是令人困惑的地方。无法相信Vue有这么大的限制
返回JSON.parse(JSON.stringify(this.items))对以下内容的更改:
让newItems=this.items.slice(0);返回新项目为什么返回数组的副本,但该副本不起作用?那么为什么你的工作呢?@soarinblue因为你不是在复制,你只是把同一个引用赋给了其他变量并返回了那个变量,所以你
changeAge: function(event){
  item = event.target.value;  // Actual assignment
}
<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>
                <item-age-input
                    :item="item"
                    @age-changed="ageChanged"></item-age-input>
            </td>
        </tr>
    </tbody>
</table>

<script>
Vue.component('item-age-input', {
    props: {
        item: {
            type: Object,
            required: true
        }
    },
    template: `<input type="text" name="qty" v-model="item.age">`,
    watch: {
        "item.age": function(newAge, oldAge) {
            this.$emit('age-changed', newAge, oldAge, this.item);
        }
    }
});

var app = new Vue({
    el:"#table1",
    data:{
        items:[{name:'long name One',age:21},{name:'long name Two',age:22}]
    },
    methods: {
        ageChanged: function(newAge, oldAge, item){
            alert(newAge + ', ' + oldAge);
            console.log(item);
        }
    }
});
</script>