请参阅下面的我的代码段。如何获得已更改模型的旧值,在这种情况下是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);
}
}
});

<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>
&#13;
我正在尝试使用手表,但我无法找到任何帮助来观察一系列物品的年龄。
答案 0 :(得分:8)
你不会像解释here那样得到元素变化的旧价值。此外,在观察对象时,在对象引用发生更改之前,您无法按照here所述获得较旧的值。
要解决这些问题,您可以创建一个计算属性,它将克隆您的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))
}
}
});
&#13;
<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>
&#13;
答案 1 :(得分:6)
此解决方案假设您仅在处理来自用户输入的更改时需要旧值,而不是通用模型更改 - 可能就是这种情况。下面我添加了一个解决方案草图,观察所有变化是否有必要,尽管可能更好地控制它们发生的地方的其他变化,而不是在这个组件中。
v-model
并将其替换为手动处理。重要的是要注意"although a bit magical, v-model is essentially syntax sugar for updating data on user input events (...)"。所以没有太大的伤害你可以删除它并直接处理事件,就像你几乎已经做的那样。
首先,将v-model
替换为:value
。输入仍将遵循item.age
更新,但不会自动更新年龄。
<input type="text" name="qty"
:value="item.age"
@change="changeAge(item,$event)">
然后,为了实际更新该值,请将item.age = event.target.value
添加到changeAge
,如下所示:
changeAge: function(item, event){
alert(item.age); // Old value
alert(event.target.value); // New value
item.age = event.target.value; // Actual assignment
}
注意:您可能希望使用@input,这是v-model实际使用的内容。
就是这样,它应该可以解决问题。如果您需要阻止更改,则可以省略分配,但是,您需要重置输入值。 item.age = item.age
的{{1}}可以解决问题,但我不太确定会这样做。
注意:Vue.set(item, 'age', item.age)
是一个字符串,如果您需要数字,请使用event.target.value
。
如果您需要观看所有更改。但是,如果您需要,也许您应该在其他地方执行此操作,而不是此组件。
我没有准备好所有细节,所以我只是草稿:在parseInt()
,而不是普通v-for
,你放置另一个组件,比如{ {1}}。你把<input>
放在上面。在组件内部,您可以创建<my-item>
并转发v-model=item
道具,并将其转发到<input>
/ value
之外。在您的组件中,单个项目是一个道具,因此您可以直接将观察者附加到它。相关文档:Component Basics,Customizing Component v-model
,Props。
答案 2 :(得分:3)
可能为时已晚。只要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);
}
}
答案 3 :(得分:2)
用值道具替换 v模型 v模型是双向绑定,它将使您的状态变得复杂 然后在更改事件中手动修改年龄属性
<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
}
}
答案 4 :(得分:2)
您可以简单地使用
<input type="text" name="qty" v-model="item.age" @change="changeAge($event)">
和
changeAge: function(event){
item = event.target.value; // Actual assignment
}
在vue方法对象中
答案 5 :(得分:1)
https://vuejs.org/v2/api/#Vue-nextTick
changeAge() {
this.$nextTick(() => {
// here the current values are set, do desired actions
})
}
答案 6 :(得分:0)
我遇到了同样的问题。我通过将输入包装在 Vue 组件中并观察包装器组件中的属性来解决它。在观察者中,我调用了 $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>