我们在Vue项目中或多或少都会用到computed和watch。两者貌似都可以监控数据,但还是有区别的。那么我们就用一个小栗子来了解一下两者的区别吧。【戳我查看官网】computed计算属性计算属性是根据数据中声明的数据或父组件传递的props中的数据计算出的一个新值。这个新值只会随着已知值的变化而变化。简而言之:该属性依赖于其他属性,并根据其他属性计算得出。
Name:{{fullName}}
......data:{firstName:'David',lastName:'Beckham'},computed:{fullName:function(){//返回method的值作为属性值returnthis.firstName+''+this.lastName}}在计算属性对象中定义计算属性的方法,就像数据中的数据属性一样,以属性访问的形式调用object,即在页面中使用{{方法名}}来显示计算结果。注意:data中不能定义计算属性fullName,data中计算属性值的相关已知值;如果在data中定义了fullName,会报错如下图:因为如果计算出来的属性值是一个函数,那么默认会是get方法,必须有返回值,而函数的返回值是属性的属性值。computed属性定义了fullName并将相应的结果返回给这个变量。变量不能被重复定义和赋值。官方文档中也强调了computed的一个重要特性,就是computed有缓存功能。比如我在页面中多次显示fullName:Name:{{fullName}}
Name:{{fullName}}
Name:{{fullName}}
名称:{{fullName}}
名称:{{fullName}}
......计算:{fullName:function(){console.log('computed')//只在控制台打印一次returnthis.firstName+''+this.lastName}}我们知道computed中定义的函数只执行一次,只有在初始化显示或相关数据、props等时才会执行attributedataoccur当计算出的属性值改变时调用;计算属性值默认会缓存计算结果,计算属性会根据它们的响应依赖进行缓存;仅当使用计算属性时,才会执行计算代码。在重复调用中,只要根据数据不变,直接取缓存中的计算结果。computed只有在相关数据发生变化时才会重新计算。高级计算属性:computed中的属性有一个get和一个set方法,当数据发生变化时,调用set方法。接下来我们通过计算属性的getter/setter方法实现属性数据的展示和监听,即双向绑定。computed:{fullName:{get(){//回调读取当前属性值,根据相关数据计算并返回当前属性的值returnthis.firstName+''+this.lastName},set(val){//属性值变化时回调,更新相关属性数据,val为fullName的最新属性值constnames=val?val.split(''):[];this.firstName=names[0]this.lastName=names[1]}}}watch监控属性通过vm对象的$watch()或watch配置监控Vue实例上的属性变化或一些特定数据的变化,然后执行一些特定的业务逻辑操作。当属性发生变化时,自动调用回调函数,并在函数内部进行计算。它可以监控的数据源:data、props、computed中的data。上面的例子是通过watch实现的:watch:{//监听data中的firstName,如果有变化,将变化后的值赋给data中的fullName,val是firstName的最新值firstName:function(val){this.fullName=val+''+this.lastName},lastName:function(val){this.fullName=this.firstName+''+val}}//从上面可以看出watch需要监控两个数据,而且代码中相同类型重复,所以比使用computed更简洁。注意:监听函数有两个参数。第一个参数是最新的值,第二个参数是输入前的值。只写一个参数,就是最新的属性值。在选择watch或者computed的时候,另一个参考点就是官网说的:当数据发生变化,需要进行异步或者开销大的操作时,watch方法是最有用的。所以watch必须支持异步。以上仅限于监控简单的数据类型,监控复杂的数据类型需要使用深度监控deep。|deep:为了发现对象内部值的变化,可以在option参数中指定deep:true。请注意,侦听数组更改不需要这样做。data:{fullName:{firstName:'David',lastName:'Beckham'}},watch:{fullName:{handler(newVal,oldVal){console.log(newVal);控制台日志(旧值);},deep:true}}上面的打印结果:newVal和oldVal的打印值是一样的,所以深度监控虽然可以监控到对象的变化,但是无法监控到对象中具体属性的变化。这是因为它们的引用指向同一个对象/数组。Vue不会保留更改前值的副本。【vm.$watch深度监控】如果想监控对象单个属性的变化,有两种方法:1、直接监控对象watch的属性:{fullName.firstName:function(newVal,oldVal){console.log(newVal,oldVal);}}2。与computed属性配合使用,computed返回你要监控的属性的值,watch用于监控computed:{firstNameChange(){returnthis.fullName.firstName}},watch:{firstNameChange(){console.log(this.fullName)}}总结:watch和computed都是基于Vue的依赖跟踪机制。当某个依赖数据(dependentdata:简单理解就是data等对象下的实例数据)发生变化时,所有依赖于该数据的相关数据都会自动发生变化,即自动调用相关函数实现数据变化。当依赖值发生变化时,watch中可以进行一些复杂的操作,而computed中的依赖只是一个值依赖于另一个值,这就是值依赖。应用场景: computed:用于处理复杂的逻辑运算;一个数据受一个或多个数据的影响;用来处理watch和method无法处理,或者不方便处理的情况。例如处理模板中的复杂表达式,购物车中商品数量与总金额的变化关系等。 watch:用于处理需要执行某些特定业务逻辑操作时属性更改,或者在数据更改时执行异步或昂贵的操作;数据更改会影响多个数据。比如用来监听路由,对input输入框值进行特殊处理等。区别: computed是在初始化显示或相关数据、道具等属性数据发生变化时调用;computed属性不在data中,它是根据data或props中的数据计算出来的一个新值,这个新值是根据已知值变化的;计算属性对象中定义计算属性的方法与数据对象中的数据属性相同,以属性访问的形式调用;如果计算属性的值是一个函数,则默认使用get方法。必须有一个返回值。函数的返回值是属性的属性值;计算属性值默认会缓存计算结果。重复调用时,只要依赖数据不变,直接取缓存中的计算结果,只有依赖数据Computed发生变化才会重新计算;在计算中,属性有一个get和一个set方法,当数据改变时,调用set方法。watch主要用来监听某些特定数据的变化,从而执行一些特定的业务逻辑操作,可以看成是computed和methods的组合;可监控的数据源:data、props、computed中的data;手表支持异步;不支持缓存,监听到的数据变化会直接触发相应的操作;监控函数有两个参数,第一个参数是最新值,第二个参数是输入前的值,顺序必须是新值,旧值。