watch 监听器
在vue中,watch可以监听数据的改变。监听之后会调用一个回调函数。回调函数又两个参数
1.更新后的值(也就是新值)
2.更新前的值(旧值)
1.简体基本数据类型
下面使用watch来监听商品数量的变化。并且设置如果商品数量小于1,就重置成上一个值。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id='app'>
<table border="1px" width="100%" style="text-align: center;">
<tr>
<th>商品编号</th>
<th>商品名称</th>
<th>商品单价</th>
<th>商品数量</th>
<th>总计</th>
</tr>
<br>
<tr>
<td>1</td>
<td>小米</td>
<td>{{price}}</td>
<td>
<button @click="sub">-</button>
{{quantity}}
<button @click="add">+</button>
</td>
<td>{{totalprice}}</td>
</tr>
</table>
</div>
<script type="text/javascript">
let vm = new Vue({
el: '#app',
data: {
price: 1999,
quantity: 1
},
methods: {
sub() {
this.quantity--;
},
add() {
this.quantity++;
},
},
computed: {
totalprice() {
return this.quantity * this.price;
}
},
watch:{
quantity(newvalue,oldvalue){
this.quantity = newvalue<0?oldvalue:newvalue;
}
}
})
</script>
</body>
</html>
在上面这个例子中就监听了商品数量quantity这个基本数据类型,当它的值小于0的时候就让它变回0。
2.深度监听
当要监听的数据类型变成了对象类型的时候,上面的这个方法就失效了,因为对于基本数据类型的监听是属于浅监听,对应的对象类型的深度监听要在上面的基础上加上deep:true 。
<div id="app">
<table width="100%" style="text-align: center;">
<tr>
<th>商品编号</th>
<th>商品名称</th>
<th>商品单价</th>
<th>商品数量</th>
<th>合计</th>
</tr>
<tr>
<td>1</td>
<td>小米10</td>
<td>{{goods.price}}</td>
<td>
<button @click="subtract">-</button>
{{goods.quantity}}
<button @click="add">+</button>
</td>
<td>{{totalPrice}}</td>
</tr>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
goods:{
price: 2999,
quantity: 1
}
},
computed: {
totalPrice() {
return this.goods.price * this.goods.quantity;
}
},
methods: {
add() {
this.goods.quantity++;
},
subtract() {
this.goods.quantity--;
}
},
watch:{
goods:{
handler(newVal,oldVal){
/**
* 注意:虽然使用深度监听,可以监听到对象的改变。
* 但是,由于是对象类型,所以newVal与oldVal都指向同一个对象。
* 所以,newVal与oldVal中的quantity都是改变后的新值。
*/
console.log(newVal,oldVal);
this.goods.quantity = newVal.quantity<=0?oldVal.quantity:newVal.quantity;
},
deep:true
}
}
});
</script>