1. 什么是JavaScript计算属性和监视属性
在Vue.js开发中,JavaScript计算属性和监视属性是常常使用的概念。这两种属性都可以帮助我们在响应式数据变化时,实现自动更新页面。下面我们来详细了解一下这两种属性。
1.1 计算属性是什么
计算属性是根据其它响应式属性计算而来的属性,计算属性的值会根据其它属性的值自动更新,这个过程是计算属性自动完成的,我们不需要在代码中手动更新。计算属性的代码示例如下所示:
data() {
return {
price: 20,
count: 2
}
},
computed: {
totalPrice() {
return this.price * this.count
}
}
在上面的示例代码中,totalPrice是一个计算属性,它的值依赖于price和count的值,每当price或count的值发生变化时,totalPrice的值也会相应的更新。总体上,计算属性的作用相当于一个函数,该函数依赖于其它属性,每当依赖属性变化时,计算属性函数会重新计算值。
1.2 监视属性是什么
监视属性可以监听某个属性的变化,从而执行一些额外操作。我们可以通过watch属性定义一个监视属性。监视属性将响应式数据与函数逻辑结合起来,我们可以在监视属性中编写函数,一旦该属性发生变化,函数就会立即执行。示例代码如下:
data() {
return {
name: '',
age: 0
}
},
watch: {
name(newName, oldName) {
console.log('name变化时执行的函数')
},
age(newAge, oldAge) {
console.log('age变化时执行的函数')
}
}
在上面的示例代码中,我们用watch属性来定义了两个监视属性name和age,这两个监视属性都有一个函数,当它所监视的属性发生变化时,相应的函数就会执行。
2. JavaScript计算属性与监视属性的应用
下面我们将通过一个实际的示例来展示JavaScript计算属性与监视属性的应用。
假设我们有一个购物车的功能,每当用户添加商品到购物车中时,我们需要计算购物车中商品的总价。我们可以通过计算属性来实现这个功能,代码如下:
data() {
return {
cart: [
{
id: 1,
name: '商品1',
price: 10,
count: 2
},
{
id: 2,
name: '商品2',
price: 20,
count: 3
}
]
}
},
computed: {
totalPrice() {
let totalPrice = 0
for (let i = 0; i < this.cart.length; i++) {
totalPrice += this.cart[i].price * this.cart[i].count
}
return totalPrice
}
}
在上面的代码中,我们用一个数组cart来存放所有的商品信息。在计算属性totalPrice中,我们使用一个循环来遍历购物车中的所有商品,然后累加每个商品的总价格。这里将累加的总价格赋值给了totalPrice,即计算属性的值。代码执行过程如下图所示:
除了计算属性之外,我们还可以使用监视属性来实现商品总价的更新功能。假设我们有一个修改商品数量的功能,当用户修改某个商品的数量时,购物车的总价也应该相应的更新。代码如下:
data() {
return {
cart: [
{
id: 1,
name: '商品1',
price: 10,
count: 2
},
{
id: 2,
name: '商品2',
price: 20,
count: 3
}
]
}
},
computed: {
totalPrice() {
let totalPrice = 0
for (let i = 0; i < this.cart.length; i++) {
totalPrice += this.cart[i].price * this.cart[i].count
}
return totalPrice
}
},
watch: {
cart: {
handler(newCart, oldCart) {
console.log('cart变化了')
console.log('newCart', newCart)
console.log('oldCart', oldCart)
},
deep: true
}
}
在上面的代码中,我们用watch属性来定义一个监视属性cart,该监视属性会立即执行一个函数,在函数中我们输出了cart变化前后的值。同时,我们在监视属性中设置了deep为true,表示我们也要监视cart数组中每个元素的改变。
接下来,我们在商品数量修改方法中,修改商品数量并手动触发cart数组的更新:
methods: {
minus(index) {
if (this.cart[index].count > 1) {
this.cart[index].count--
this.$set(this.cart, index, this.cart[index])
}
},
add(index) {
this.cart[index].count++
this.$set(this.cart, index, this.cart[index])
}
}
在上面的代码中,我们先判断了商品数量是否大于1,如果大于1,就把商品数量减1。当用户点击减少按钮时,会触发minus方法,在方法中我们通过$set方法手动触发cart数组的更新。$set方法会通知Vue.js,cart数组的变化已经发生,从而触发监视属性的执行。
当我们运行代码时,我们发现在minus方法中每一次手动触发更新商品数量时,console窗口中都会出现cart变化前后的值,证明了监视属性的执行。同时,我们注意到在执行minus方法后,购物车的总价也被自动更新了,这是因为购物车中的商品数量的变化触发了计算属性totalPrice的自动更新,进而重新计算了购物车的总价。
3. JavaScript计算属性和监视属性的注意点
3.1 计算属性的缓存
计算属性是有缓存的,Vue.js会对计算属性进行缓存,只有当计算属性依赖的响应式数据发生改变时,才会重新计算计算属性的值。这种缓存机制可以优化代码的性能,减少计算属性的计算次数。我们可以通过watch属性来监视计算属性的变化,如下所示:
computed: {
totalPrice() {
let totalPrice = 0
for (let i = 0; i < this.cart.length; i++) {
totalPrice += this.cart[i].price * this.cart[i].count
}
return totalPrice
}
},
watch: {
totalPrice(newVal, oldVal) {
console.log('totalPrice被修改了')
console.log('newVal', newVal)
console.log('oldVal', oldVal)
}
}
在上面的代码中,我们用watch属性来监视了计算属性totalPrice的变化,当计算属性totalPrice的值发生变化时,函数就会被立即执行。
3.2 监视对象、数组的变化
对于一个对象或数组,它的每个元素都有自己的引用地址,所以在监视对象、数组的变化时,我们需要设置deep为true,这样才能够正确的监视到所有元素的变化。代码示例如下:
watch: {
cart: {
handler(newCart, oldCart) {
console.log('cart变化了')
console.log('newCart', newCart)
console.log('oldCart', oldCart)
},
deep: true
}
}
在上面的代码中,我们通过设置deep为true,来监视cart数组中每个元素的变化。
4. 结束语
JavaScript计算属性和监视属性是Vue.js框架中非常重要的概念。使用计算属性和监视属性,我们可以非常方便地实现响应式数据的变化,从而减少开发难度和提高代码性能。在实际应用开发中,我们需要根据具体情况灵活使用计算属性和监视属性,来达到认为的开发效果。