计算属性(computed)和监听器(watch)的区别

引言

在学习Vue的过程中,我们经常会使用计算属性来作为输出在页面中的数据内容,发现使用计算属性非常方便,但是学到后面我们又会发现一个叫侦听器的东西。

那么问题来了,侦听器和计算属性,哪个更牛逼,哪个更好用?

不少刚刚学习Vue的小白都会纠结这个问题,但是实际上我想给这些小白同学说,不用纠结,计算属性和侦听器咋一看上去使用方式,结果都差不多,但是理解了他们深层次的原理之后你就会发现,他们其实是用在不同情况下的。

那么就意味着,只有在符合特定情况下时,我们就会使用相对该情况最合适的特性来完成计算,显示数据的操作。

分析

那么,我们应该在什么情况下使用计算属性,什么情况下使用侦听器呢?

不忙,我们先来各自回顾一下这两个特性的基本使用语法:

1).计算属性:
<div id="app">  {{total}}  </div>

<script>
    var vm = new Vue({  
        el: '#app',  
        data: {  
            num: 10,  
            price: 8.8,  
        },  
        computed: {  
            total: function () {  
                return this.num * this.price  
            }  
        }  
    })
</script>
2).侦听器:
<div id="app">  {{total}}  </div>

<script>
    var vm = new Vue({  
        el: '#app',  
        data: {  
            num: 10,  
            price: 8.8,  
        },  
        watch: {  
            num: function (val) {  
                this.total = val * this.price  
            },
            price: function (val) {
                this.total = this.num * val
            }
        }  
    })
</script>

通过上面的两个案例,我们稍微回顾了一下计算属性和侦听器的用法。
我们其实可以从多个方面来分析这两个东西的区别,以此寻求适合这两种特性使用的情况。

计算属性的特点:

当我们定义一个计算属性的时候,计算属性是一个函数,最后函数返回的结果就是计算属性得到的结果。
当我们去第一次使用计算属性的时候,会执行计算属性并进行计算,然后将计算的结果缓存起来。
后续当我们再去使用计算属性的时候,如果计算属性中使用到的数据没有发生变化,那么就会直接读取缓存的结果,不会重新计算。

带入到我们所写的案例中,就是这样的一个情形:
我们定义了一个total计算属性,当我们使用插值表达式{{total}}时,会去执行total这个计算属性。
在total计算属性中,使用this.num * this.price得到一个total总价作为计算属性的结果,最后会将计算出来的总价88缓存起来。
当我们下一次使用插值表达式{{total}}或者其他方式使用计算属性total的时候,就会检查计算属性中使用的this.num或者this.price有没有发生变化
如果this.num或者this.price没有发生变化,直接获取缓存的总结88作为计算属性的结果。
如果this.num或者this.price任何一项发生了变化,那么就会重新计算并得到一个总结结果,并重新将结果进行缓存。

注意:
每次计算的结果缓存的时候,都会重新创建一个变量保存结果。

侦听器的特点:

当我们定义一个侦听器的时候,侦听器与data中的属性同名,当属性的值发生改变的时候,侦听器被触发执行。

带入到我们所写的案例中,就是酱紫的一个情形:
我们定义了两个侦听器,侦听num和price的变化,当我们改变num或者price的时候,会触发对应的侦听器。
在两个侦听器中,刚好做的都是将最新的num乘以最新的price得到一个总价并赋值给data中的total。

注意:
一个侦听器对应data中的一个属性,当属性发生变化时触发侦听器的执行。

分析结果:

从上面的特点来说,我们可以得出结论:
1).计算属性的应用场景是计算的内容需要依赖多个属性的情况
侦听器的应用场景是计算的内容依赖一个属性的情况
2).计算属性缓存结果时每次都会重新创建变量
而侦听器是直接计算,不会创建变量保存结果
也就意味着,数据如果会反复的发生变化,计算很多次的情况下,计算属性的开销将会更大,也就意味着这种情况不适合使用计算属性,适合使用侦听器
那么,如果一个数据反复会被使用,但是它计算依赖的内容很少发生变化的情况下,计算属性会缓存结果,就更加适合这种情况。
3).computed的结果是通过return返回的,而watch不需要return。
4).watch中的参数可以得到侦听属性改变的最新结果,而computed函数没有这种参数。

补充:
watch只会监听数据的值是否发生改变,而不会监听地址的变化,如果需要监听引用类型的数据变化,需要深度监听:obj:{handler(newVal){},deep:true}------用handler+deep的方式进行深度监听。
在特殊的情况下(更改数组中的数据时,数组已经更改,但是视图没有更新),watch无法监听数组的变化,更改数组必须要用splice()或者$set。

结论:

我们在计算开销比较大(计算次数多或者异步处理)的时候,会使用侦听器watch来得到计算结果。
而其他情况建议使用计算属性computed,因为缓存节省多次计算的性能。

  • 25
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue中,计算属性监听器都是响应数据变化的方式,但是它们的用法和作用略有不同。 计算属性是基于响应式数据计算而来的属性,当计算属性所依赖的数据发生变化时,计算属性会自动重新计算。计算属性的特点是可以缓存结果,只有在计算属性所依赖的数据发生变化时才会重新计算。计算属性通常用于需要依赖多个数据计算得出的值,或者需要对数据进行处理后返回一个新的值的情况。 ```html <template> <div> <p>{{ fullName }}</p> </div> </template> <script> export default { data() { return { firstName: 'John', lastName: 'Doe' } }, computed: { fullName() { return `${this.firstName} ${this.lastName}` } } } </script> ``` 在上面的示例中,`fullName`是一个计算属性,它依赖于`firstName`和`lastName`两个响应式数据,当`firstName`或`lastName`发生变化时,`fullName`会自动重新计算。 监听器是用于监听某个数据的变化,当该数据发生变化时,监听器会执行指定的回调函数。监听器的特点是不能缓存结果,每次数据变化时都会执行回调函数。监听器通常用于需要在数据变化时执行一些异步操作的情况。 ```html <template> <div> <p>Name: {{ name }}</p> </div> </template> <script> export default { data() { return { firstName: 'John', lastName: 'Doe' } }, computed: { name() { return `${this.firstName} ${this.lastName}` } }, watch: { name(newName, oldName) { console.log(`Name changed from ${oldName} to ${newName}`) } } } </script> ``` 在上面的示例中,`name`是一个计算属性,它依赖于`firstName`和`lastName`两个响应式数据,当`firstName`或`lastName`发生变化时,`name`会自动重新计算。同时,我们定义了一个监听器监听`name`的变化,当`name`发生变化时,回调函数会被执行。注意,监听器的回调函数接受两个参数,分别是新值和旧值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值