本文讨论一下计算属性和侦听器相关的用法
直接上代码
1. 计算属性
<!-- HTML -->
<div id="app">
我的购物车:<br>
<ul>
<li v-for="(item, index) in cart" :key="index">
商品名称:{{item.name}} 商品单价:{{item.price}} 商品库存:{{item.stock}}
<input type="number" v-model="item.num">
</li>
</ul>
总价:{{ calculateTotalPrice() }}
</div>
// JS
<script>
let app = new Vue({
el: '#app',
data: {
cart: [
// stock表示库存
{ name: '苹果手机', price: 1000, stock: 10, num: 1 },
{ name: '小米手机', price: 500, stock: 10, num: 1 }
],
text: 'test'
},
methods: {
// 使用函数来计算总价
calculateTotalPrice() {
console.log('计算总价')
let totalPrice = 0;
this.cart.forEach(item => {
totalPrice += item.price * item.num
});
return totalPrice
}
}
})
</script>
运行:

当然,总价的计算也可以通过计算属性来实现
<!-- HTML -->
<div id="app">
我的购物车:<br>
<ul>
<li v-for="(item, index) in cart" :key="index">
商品名称:{{item.name}} 商品单价:{{item.price}} 商品库存:{{item.stock}}
<input type="number" v-model="item.num">
</li>
</ul>
总价:{{ totalPrice }} <!-- 注意计算属性是一个属性,不能像调用方法一样使用:totalPrice() -->
</div>
// JS
<script>
let app = new Vue({
el: '#app',
data: {
cart: [
{ name: '苹果手机', price: 1000, stock: 10, num: 1 },
{ name: '小米手机', price: 500, stock: 10, num: 1 }
],
text: 'test'
},
computed: {
// 计算属性
totalPrice() {
console.log('计算属性重新计算数值')
let total = 0;
this.cart.forEach(item => {
total += item.price * item.num
});
return total;
}
}
})
</script>
计算属性和函数最大的区别是,只有当相关联的属性发生变化时,计算属性才会被重新计算,也就是说,在本例中,只有cart值发生变化,计算属性才会被重新计算。并且计算属性的值有缓存,取值时无需重复计算;对于函数,我们定义的data中的任意数据发生变化,如果导致节点刷新,函数都会重新执行(比如页面中使用了text属性,当修改了text属性值,此时节点需要刷新,计算总价的函数也会重新执行)。
2. 侦听器
我们想实现一个功能,在num超过stock时进行提示,先通过函数来实现
<!-- HTML -->
<div id="app">
<br>
我的购物车:<br>
<ul>
<li v-for="(item, index) in cart" :key="index">
商品名称:{{item.name}} 商品单价:{{item.price}} 商品库存:{{item.stock}}
<input type="number" v-model="item.num">
</li>
</ul>
总价:{{ calculateTotalPrice() }}<br>
<span v-html="refreshMessage()"></span>
</div>
// JS
<script>
let app = new Vue({
el: '#app',
data: {
cart: [
{ name: '苹果手机', price: 1000, stock: 10, num: 1 },
{ name: '小米手机', price: 500, stock: 10, num: 1 }
],
text: 'test',
message: ''
},
methods: {
calculateTotalPrice() {
console.log('执行计算函数');
let totalPrice = 0;
this.cart.forEach(item => {
totalPrice += item.price * item.num
});
return totalPrice;
},
refreshMessage() {
message = '';
this.cart.forEach(element => {
if(element.num > element.stock) {
message += `${element.name}超出库存了<br>`;
}
});
return message;
}
}
})
</script>
运行:

通过侦听器来实现信息提示
<!-- HTML -->
<div id="app">
<br>
我的购物车:<br>
<ul>
<li v-for="(item, index) in cart" :key="index">
商品名称:{{item.name}} 商品单价:{{item.price}} 商品库存:{{item.stock}}
<input type="number" v-model="item.num">
</li>
</ul>
总价:{{ calculateTotalPrice() }}<br>
<span v-html="message"></span>
</div>
// JS
<script>
let app = new Vue({
el: '#app',
data: {
cart: [
//
{ name: '苹果手机', price: 1000, stock: 10, num: 1 },
{ name: '小米手机', price: 500, stock: 10, num: 1 }
],
text: 'test',
message: ''
},
methods: {
calculateTotalPrice() {
console.log('执行计算函数')
let totalPrice = 0;
this.cart.forEach(item => {
totalPrice += item.price * item.num
});
return totalPrice
}
},
watch: {
// 非数组或对象的属性这样使用即可
text(newValue, oldValue) {
console.log('watch text')
console.log(newValue, oldValue)
},
cart: {
handler(newValue, oldValue) {
console.log('watch cart')
this.message = '';
this.cart.forEach(element => {
if(element.num > element.stock) {
this.message += `${element.name}超出库存了<br>`;
}
});
},
// 注意:如果是侦听数组或者对象应该进行深度侦听.加上此属性
deep: true
}
}
})
</script>
注意,在此功能的实现上,使用函数和侦听器有一些差别。对于侦听器来说,只有当所侦听的数据发生变化时才会执行相应代码,如果初始化 cart 的时候,num就已经大于stock,并不会触发执行侦听器中的代码,因为数据并没有发生变化。如果使用函数来实现,初始时num大于stock,可正常触发提示。
本文通过购物车示例,介绍了Vue.js中计算属性与侦听器的使用方法及区别。展示了如何利用计算属性高效地计算总价格,以及如何使用侦听器响应数据变化并给出提示。
1156

被折叠的 条评论
为什么被折叠?



